【问题标题】:is a gen_server is up?gen_server 是否已启动?
【发布时间】:2011-09-22 11:00:03
【问题描述】:

有没有办法告诉一个gen_server:“主管已经初始化了所有的gen_servers,现在你可以发送消息了”?

我有一个工人 gen_server,他的工作是在他的监督树中设置其他 gen_servers 的状态。如果我刚开始在配置服务器的 init 函数中发送消息,有时它会得到 {noproc, _}。我想这意味着配置服务器很快:他在主管有足够的时间启动所有工作人员之前发送了消息。我通过将 timer:sleep(500) 放入 config_server:init() 来解决这个问题,这可以确保所有 gen_server 都有足够的时间来初始化,但这似乎是一个不优雅的解决方案。

有没有合适的方法来做到这一点?

【问题讨论】:

    标签: erlang erlang-otp erlang-supervisor gen-server


    【解决方案1】:

    init 返回具有超时0 的元组。然后在它返回后立即调用handle_info(timeout, State)。在handle_info 中进行一些调用,该调用在主管完成初始化之前不会返回(例如supervisor:which_children)。

    【讨论】:

    • 注意:不能在init 中调用supervisor:which_children,因为在主管知道子进程已正确初始化之前,子进程调用proc_lib:init_ack。超时解决方案解决了这个问题,但 send_cast 也可以。
    【解决方案2】:
    info(PlayerId) ->
    Pid = case global:whereis_name(util:getRegName({?MODULE, PlayerId})) of
        P when is_pid(P) ->
            P;
        _ ->
            {ok, P} = player_sup:start_child(PlayerId),
            P
    end,
    gen_server:call(Pid, info).
    

    这是我处理这个问题的案例。这个工作进程只有在被请求时才会被触发。

    【讨论】:

      【解决方案3】:

      在函数init() 中调用gen_server:cast(init, State)。消息“init”将在消息队列中排在第一位

      【讨论】:

        猜你喜欢
        • 2011-06-18
        • 2011-10-16
        • 2017-01-28
        • 1970-01-01
        • 2011-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多