3

我们有一个 gen_server 进程,它通过创建被动套接字池并将它们借给其他进程来管理客户端的被动套接字池。任何其他进程都可以借用套接字,使用套接字向服务器发送请求,通过 gen_tcp:recv 得到答复,然后将套接字释放给 gen_server 套接字池进程。

套接字池进程监视所有借用套接字的进程。如果任何借用的进程宕机,它会从它那里得到一个宕机信号:

handle_info({'DOWN', Ref, process, _Pid, _Reason}, State) ->

在这种情况下,我们想清空借来的套接字,并通过放回池中来重用它。问题是,在尝试使用 清空套接字gen_tcp:recv(Socket, 0, 0)时,我们收到 inetealready错误消息,这意味着recv操作正在进行中。

所以问题是如何中断先前recv的,成功地排空一个套接字,并为其他进程重用。

谢谢。

4

1 回答 1

2

再增加一层间接性将大大简化情况。

与其将套接字传递给需要使用它们的进程,不如让每个套接字由一个单独的进程控制,该进程拥有它并代表系统中的套接字。根据需要在套接字之间路由 Erlang 端消息以实现套接字的“借用”(更灵活的是,向套接字控制器传递一个使用给定协议的回调模块,以便一旦数据通过网络,它就会被解释为Erlang 内部消息)。

如果这样做了,您将不会失去对套接字的控制或使它们处于不确定状态——它们将一直由一个拥有的进程持有。不要让 route-manager/pool-manager 进程接收'DOWN'消息,而是让套接字控制器监视其当前使用进程。收到a'DOWN'后,您可以根据需要更改状态。

您可能会遇到一些奇怪的情况,在未指定为所有者的套接字之间传递打开的文件描述符、套接字和其他类型的端口。如果您需要跨多个节点扩展程序,那么传递端口和套接字也会成为一个问题(突然间,您必须关心事物在哪里传递以及它们在哪个节点上,等等)。

于 2015-12-03T23:31:05.433 回答