我正在阅读 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_sup
和my_server
。 UDP连接在活动模式下以my_server
打开,以便在每个新UDP消息上调用handle_info/2
以响应我呼叫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
用作工厂,但我只使用工作人员的init/1
和handle_info(timeout,State)
功能首先设置状态,然后在关闭工作人员之前处理消息。
我应该直接产生工人吗?或许是另一种行为更适合吗?
谢谢, HC
答案 0 :(得分:4)
这个问题的关键答案是:“你希望你的应用程序如何崩溃?”
如果一个工人死了,那会发生什么?如果这应该停止一切,包括UDP连接,那么你肯定可以直接在my_server下生成它们,不需要管理树。但是如果你希望它们能够优雅地重启或其他什么,那么上面的图表通常会更好。也许可以在my_server中为工作人员添加一个监视器,这样就可以保存一本关于谁还活着的书。
在我的utlang文件库中,我的构造几乎相同。主服务器处理UDP套接字并根据保留在ETS中的路由表转发给工作服务器。每个工作人员都保持连接状态,并可以处理传入的信息。
由于您没有跟踪状态,因此最好的选择可能是通过proc_lib:spawn_link
运行,然后将它们作为临时进程挂钩到s_1_1主管。这样,您将强制过多的崩溃在主管树上传播,但允许它们以normal
退出。这允许您让它们运行一次。
请注意,您也可以直接在my_server中处理所有内容,但之后您将无法同时处理数据。这可能是也可能是不可接受的。一般规则是当你有并发工作需要彼此相邻执行,块或以某种方式行为时产生一个新进程。