【问题标题】:What OTP behaviors should I use for this?我应该为此使用哪些 OTP 行为?
【发布时间】:2011-11-21 12:31:07
【问题描述】:

我有一个接受 TCP 连接的服务器(使用 gen_tcp 的 gen_server),并为每个连接生成一个主管。该主管(由另一个更永久的主管监督)然后产生两个进程:一个特定于协议的处理程序和一个与数据库对话的客户端上下文。

协议处理程序从套接字获取 TCP 消息并将它们转换为客户端上下文的消息。客户端上下文获取这些消息并与数据库对话并返回消息,协议处理程序通过 TCP(telnet、ssh、websockets、HTTP...)将其转换为它使用的任何协议,然后将它们发送回客户端。

我想知道哪些 OTP 行为适合协议处理程序和客户端上下文进程。我可以滥用 gen_server,但它是每个进程对 1 个连接。 gen_fsm 看起来它可以用于协议处理程序,因为它经历了几个状态,但它非常不适合客户端上下文。我正在考虑将 gen_event 用于客户端上下文,但我被引导相信它更多地用于事件聚合器,并且它只处理来自单一来源的事件。

请随时告诉我,我的做法完全错误,这是我第一次尝试在这个复杂的地方创建 OTP 应用程序。

【问题讨论】:

  • 另外考虑一下:你真的需要两个进程吗?他们同时做任何事情吗?有时,如果交互是连续的,一个进程保持两种不同的状态就足够了。
  • @Adam:我想要两个独立进程的原因是我可以将不同的连接处理程序插入同一个客户端上下文。这似乎是 Erlangiest 的做法。如果我在 Python 或其他东西中这样做,我会使用两个类。这看起来合乎情理吗?
  • 您还可以在进程启动时参数化连接处理程序的模块名称,例如spawn(client, start, [my_connection_handler, OtherData])
  • 区分并发活动(需要多个进程)和划分职责(可能只是在同一进程中运行的不同库)之间的区别很重要。
  • @Adam:可靠性怎么样?如果它们在同一个进程中,我必须在客户端上下文遇到错误时使用 TCP 连接重新启动进程(这可能会产生不良的副作用;我打算暂时保留它们)。

标签: erlang erlang-otp


【解决方案1】:

听起来您正在尝试重新实现在Cowboy 中找到的接受器池。这个应用程序将自己伪装成一个小型 HTTP 服务器,但实际上它的核心只是一个套接字服务器,看看 Andrew Thompson 如何将它用于自己的gen_smtp

【讨论】:

  • 谢谢!我寻找这样的东西,但发现偏航。它似乎比我需要的要复杂。
【解决方案2】:

我认为不需要使用主管对这两个进程进行“分组”。因此,TCP 协议处理程序的单个主管(假设它们是单例的),以及客户端上下文 gen_server 的 simple_one_for_one。当接收到新连接时,simple_one_for_one 主管被要求创建一个新的客户端上下文 gen_server。确保这两个进程知道彼此的 Pid,以便它们可以通信,并可能将它们链接起来以进行错误处理。

【讨论】:

  • 我打算使用主管对它们进行分组的原因是我可以使用 rest_for_one 并让死连接杀死上下文。
猜你喜欢
  • 2012-06-09
  • 2017-08-11
  • 1970-01-01
  • 2015-08-14
  • 2014-04-21
  • 2014-12-27
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
相关资源
最近更新 更多