erlang - 在 init 中向 self() 发送消息是不是很糟糕?

标签 erlang erlang-otp

this例如,作者通过执行以下操作避免了死锁情况:
self() ! {start_worker_supervisor, Sup, MFA}
在他的 gen_server 的 init 函数中。我在我的一个项目中做了类似的事情,并被告知这种方法不受欢迎,最好立即超时。接受的模式是什么?

最佳答案

Erlang 19+ 的更新
考虑使用新的 gen_statem 行为。此行为支持生成 FSM 内部的事件:

The state function can insert events using the action() next_event and such an event is inserted as the next to present to the state function. That is, as if it is the oldest incoming event. A dedicated event_type() internal can be used for such events making them impossible to mistake for external events.

Inserting an event replaces the trick of calling your own state handling functions that you often would have to resort to in, for example, gen_fsm to force processing an inserted event before others.


使用 action functionality在该模块中,您可以确保您的事件在 init 中生成并且总是在任何外部事件之前处理,特别是通过创建 next_event您的 init 中的操作功能。
例子:
...

callback_mode() -> state_functions.

init(_Args) ->
    {ok, my_state, #data{}, [{next_event, internal, do_the_thing}]}

my_state(internal, do_the_thing, Data) ->
    the_thing(),
    {keep_state, Data);
my_state({call, From}, Call, Data) ->
    ...

...
旧答案
在设计 gen_server 时您通常可以选择在三种不同的状态下执行操作:
  • 启动时,在 init/1
  • 运行时,在任何 handle_*功能
  • 停止时,在 terminate/2

  • 一个好的经验法则是在对事件(调用、转换、消息等)采取行动时在处理函数中执行一些事情。在 init 中执行的东西不应该等待事件,这就是句柄回调的用途。
    因此,在这种特殊情况下,会生成一种“假”事件。我想说 gen_server总是想启动主管的启动。为什么不直接在 init/1 中做呢? ?是否真的需要能够在其间处理另一条消息(在 handle_info/2 中处理的效果相反)?该窗口非常小(从 gen_server 开始到将消息发送到 self() 之间的时间),所以它根本不可能发生。
    至于死锁,我真的建议不要在你的 init 函数中调用你自己的主管。那只是不好的做法。启动工作进程的一个好的设计模式是一个顶级主管,下面有一个经理和一个工作主管。经理通过调用 worker 主管来启动 worker :
    [top_sup]
      |    \
      |     \
      |      \
     man  [work_sup]
           /  |  \
          /   |   \
         /    |    \
        w1   ...   wN
    

    关于erlang - 在 init 中向 self() 发送消息是不是很糟糕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6052954/

    相关文章:

    binary - 全二进制输出

    parsing - 将元组的字符串表示形式转换为真实元组

    events - 确保在 Erlang/OTP 中切换 gen_event 处理程序时处理事件

    erlang - erlang 中是否有生成术语或字符串哈希码的库或函数?

    java - erlang 可以处理多少并发 http 请求

    erlang - gen_fsm 的唯一原子 :start/3 in Erlang

    erlang - 如何让行为回调函数不被实现?

    database - 用于存储消息的 ejabberd mod_archive_odbc 表

    java - 从 Java 获取 Ping 到 Erlang

    erlang - 使用暗模式修复 OSX 上的 Erlang 观察器