我们有一个gen_server进程,通过创建它们并为其他进程借用它们来管理客户端上的被动套接字池。任何其他进程都可以借用套接字,使用套接字向服务器发送请求,通过gen_tcp:recv获取回复,然后将套接字释放到gen_server套接字池进程。
套接字池进程监视借用套接字的所有进程。如果任何借用的进程停止运行,它会收到一个向下信号:
handle_info({'DOWN', Ref, process, _Pid, _Reason}, State) ->
在这种情况下,我们想要耗尽借来的套接字,并通过放回池中重复使用它。问题是,在尝试使用gen_tcp:recv(Socket, 0, 0)
排空套接字时,我们会收到inet ealready
错误消息,这意味着recv
操作正在进行中。
所以问题是如何中断以前的recv
,成功地耗尽套接字,并重用其他进程。
感谢。
答案 0 :(得分:2)
另一个间接层将大大简化这种情况。
不是将套接字传递给需要使用它们的进程,而是让每个套接字由一个拥有它的单独进程控制,代表系统中的套接字。根据需要将Erlang端消息路由到套接字以及从套接字路由以实现套接字的“借用”(甚至更灵活地,将套接字控制器传递给说出给定协议的回调模块,因此只要数据通过网络传递就会被解释为内部的Erlang消息。)
如果这样做,你将不会失去对套接字的控制或使它们处于不确定的状态 - 它们将在整个时间由一个拥有的进程保持。而不是让路由管理器/池管理器进程接收'DOWN'
消息,让套接字控制器监视其当前使用过程。收到'DOWN'
后,您可以根据需要更改状态。
您可以在一些奇怪的情况下发现自己在未被指定为其所有者的套接字中传递打开文件描述符,套接字和其他类型的端口。如果你需要跨多个节点扩展程序(突然你必须关心传递的东西以及它们所在的节点等),传递端口和套接字也会成为一个问题。