如何构建一个Erlang OTP UDP服务器

3

我正在阅读Manning出版社的《Erlang & OTP实战》。我认为这是一本非常好的书。它包含一个不错的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。在 my_server 中以主动方式打开 UDP 连接,以便对每个新的 UDP 消息调用 handle_info/2,并在响应中调用 my_worker_sup:start_child/2 将消息传递给一个新的工作进程进行处理。(根据书本推荐,最后一次对 start_child/2 的调用实际上被包装在一个 API 函数中,隐藏了一些细节,但基本上就是这样发生的。)
我是否正在遭受 OTP 狂热?my_worker_server 是否真的需要实现 gen_server 行为?我是否需要使用 my_worker_sup
我这样设置是为了可以通过 start_child/2 调用使用 my_worker_sup 作为一个工厂,但我只使用 worker 的 init/1handle_info(timeout, State) 函数来首先设置状态,然后处理消息,最后关闭 worker。
我应该直接生成 worker 吗?或者可能有更适合的行为吗?
谢谢, HC

我认为我可能已经找到了如何将工作进程适配到OTP作为“特殊进程”的答案,可以在这里查看http://www.erlang.org/doc/design_principles/spec_proc.html#id72749。 - hcvst
1个回答

4
这个问题的关键答案是:“你希望你的应用程序如何崩溃?
如果一个工作进程死了,那么应该发生什么?如果这应该停止一切,包括UDP连接,那么你可以直接在my_server下spawn_link它们,不需要监督树。但是,如果您希望它们能够优雅地重启或执行其他操作,则通常最好使用上面的图表。也许从my_server对工作进程添加监视器,以便它可以记录谁还活着。
在我的utp erlang库中,我几乎有相同的结构。主节点处理UDP套接字并根据在ETS中保留的路由表转发到工作进程。每个工作进程都保持连接状态并可以处理传入信息。
由于您不跟踪状态,所以您最好通过proc_lib:spawn_link运行,然后将它们挂钩到s_1_1监督器作为瞬态进程。这样,您将强制太多的崩溃向上传播到监督树,但允许它们以normal退出。这使您能够让它们仅运行一次。
请注意,您也可以直接在my_server中处理所有内容,但是这样您将无法并发处理数据。这可能是可以接受的,也可能不可接受。一般规则是在需要并发执行工作、阻塞或以某种方式行为的情况下生成新进程。

非常感谢您的回答。不,我不想让整个服务器崩溃。我正在尝试编写一个DNS服务器https://github.com/hcvst/erlang-dns。我甚至没有考虑过可能需要跟踪连接。你所说的那个库是什么?我可以学习一下吗?再次感谢,HC。 - hcvst
当然可以:https://github.com/jlouis/erlang-utp/blob/master/src/utp_sup.erl - gen_utp 运行接受队列和套接字。gen_utp_decoder 是解码器和分发器。将其保持分离以处理崩溃。最后,工作池包含已分派的工作进程。研究进程表的簿记 - 但我的思维过程可能是错误的,所以请注意。 - I GIVE CRAP ANSWERS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接