3

我只是在阅读Manning 的 Erlang & OTP In Action。很不错的书,我觉得。它包含一个不错的 TCP 服务器示例,但我想编写一个 UDP 服务器。到目前为止,这就是我构建应用程序的方式。

my_app                        % app behaviour
|-- my_sup                    % root supervisor 
    |-- my_server.erl         % gen_server to open UDP connection and dispatch
    |-- my_worker_sup         % simple_one_to_one supervisor to start workers
        |-- my_worker_server  % gen_server worker 

所以,my_app开始my_sup,然后开始my_worker_supmy_server。UDP 连接my_server在活动模式下打开,以便handle_info/2在每个新的 UDP 消息上调用,作为响应,我调用my_worker_sup:start_child/2该消息将消息传递给新的工作进程进行处理。(实际上,根据本书的建议,最后一次调用start_child/2是封装在一个 API 函数中以隐藏一些细节,但这实际上就是发生的情况。)

我是否患有 OTP 发烧?应该my_worker_server真正实现 gen_server 行为吗?我需要my_worker_sup吗?

我是这样设置的,这样我就可以my_worker_sup通过调用将其用作工厂,start_child/2但我只使用 workerinit/1handle_info(timeout,State)函数来首先设置状态,然后在关闭 worker 之前处理消息。

我应该直接产生工人吗?也许另一种行为更适合?

谢谢,慧聪

4

1 回答 1

4

这个问题的关键答案是:“你希望你的应用程序如何崩溃?

如果工人死了,那该怎么办?如果这应该停止一切,包括 UDP 连接,那么您当然可以直接在 my_server 下 spawn_link 它们,不需要主管树。但是如果你想让它们能够优雅地重启或者别的什么,那么上图通常会更好。也许在 my_server 的工作人员上添加一个监视器,这样它就可以保存一本关于谁还活着的书。

在我的 utp erlang 库中,我的结构几乎相同。Master 处理 UDP 套接字并根据 ETS 中保存的路由表转发给 worker。每个worker保持一个连接状态并且可以处理传入的信息。

由于您不跟踪状态,那么您最好的选择可能是通过运行proc_lib:spawn_link,然后将它们作为瞬态进程连接到 s_1_1 主管。这样,您将强制将过多的崩溃传播到主管树,但允许它们以normal. 这使您可以让它们只运行一次。

请注意,您也可以直接在 my_server 中处理所有内容,但是您将无法同时处理数据。这可能会或可能不会被接受。一般规则是当您有并发工作需要彼此相邻执行、阻塞或以某种方式表现时,生成一个新进程。

于 2012-12-12T11:56:29.833 回答