【问题标题】:Communication between Erlang Gen Server'sErlang Gen Server 之间的通信
【发布时间】:2011-04-19 04:18:03
【问题描述】:

我正在使用 Erlang OTP 框架构建一个网络路由器应用程序。

在其运行 Supervisor 的过程中,创建了两个 genservers,每个 estagen_server:call(CurrentProcName,{BinEvent,UniqueTrxId,MdPid},infinity) 建立一个到两个单独服务器的 tcp 连接。

现在在运行应用程序时,恰好一个 genserver 接收到重复事件,在这种情况下,我希望该事件由第二个 gen_server 处理。

为此,我正在调用 gen_server:call(NextProcName,{BinEvent,UniqueTrxId,MdPid},infinity),

当重复事件的条件满足时,我在 gen_server 模块中调用此函数。

NextProcName :: 第二个gen_server的注册名

注意 :: 两个 gen_server 的代码保持不变

问题是我能够复制事件,但事件不知何故没有传递到第二个 gen_server :(

如果我做错了,请提出建议。

【问题讨论】:

    标签: erlang


    【解决方案1】:

    如能分享出处,不胜感激。

    您确定确实收到了消息,还是只是没有收到答复?

    我在这里看到的最合理的问题是您正在以同步方式转发消息。如果不是这种情况,那么您可以完全无视我的帖子。现在,让我们看看同步转发是如何发挥作用的:

     client          server1             server2
       |                |                   |
       >--- Msg1 ----> (ok)                 |
    (waits S1)          |                   | 
      (ok) <-- Reply ---<                   |
       >--- Msg2 ----> (ok)                 |
    (waits S1)          >----- Msg2 -----> (ok)
    (waits S1)      (waits S2) <--- Reply --<      
    (waits S1)      (Waits S2)              |
    
              *Stuff crashes*
    

    这并不完全清楚,但它显示了正在发生的事情。这里Server1 基本上仍然算作将消息Msg2 处理到gen_server 行为,因此永远不会读取它正在等待的Server2 的回复。这通常会以超时和崩溃告终。

    执行此操作的正确方法是改为从Server1Server2 发送一个异步调用(cast),包括From 变量,以便Server2 可以回复gen_server:reply/2 来替换自己到Server1。然后Server1 应该返回一个noreply 元组。这将释放Server1 的进程,它可以继续处理其他内容。

    【讨论】:

    • 你肯定不会给出糟糕的建议:P.
    • 我很抱歉目前无法分享代码。但我会尽我的能力在此线程中将条件解释为答案而不是评论。
    猜你喜欢
    • 2011-08-19
    • 2013-08-29
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    相关资源
    最近更新 更多