单独终止simple_one_for_one个孩子

时间:2012-11-15 16:12:45

标签: erlang otp

我有一个由gen_servers组成的监督树作为临时子女,它的寿命很短。在清理和终止时,每个孩子都会收到一条消息。

有一个控制器进程可以保护这些孩子的Pid字典,受到我从tinymq项目中读取的代码的启发。

在他们的情况下,他们使用max_age设置过期他们的频道,其中code我不太明白。

在我的情况下,我在做一些清理之后尝试使用supervisor:terminate_child(Sup, Pid),如下所示:

孩子本身在控制器上执行RPC:

fs_outbound_controller:deallocate_me(UUID, self());

控制器:

deallocate_me(UUID, Pid) ->
    gen_server:cast(?SERVER, {deallocate_me, UUID, Pid}).

handle_cast({deallocate_me, UUID, Pid}, #state{dict = Uuid2Pid} = State) ->
    NewDict = dict:erase(UUID, Uuid2Pid),
    supervisor:terminate_child(fs_outbound_extn_sup, Pid),
    error_logger:info_msg("Successfully deallocated ~p", [UUID]),
    {noreply, State#state{dict=NewDict}}.

我观察到的问题是ERROR记录器报告了gen_server终止返回值的崩溃?

** Reason for termination == 
** {bad_return_value,ok}

感谢您的帮助。

修改

我做了别的事情,我将调用从RPC调用deallocate_me到从子节点到控制器的消息。想到孩子正在对控制器进行RPC调用,而这个控制器已经终止了孩子,这导致了一些返回问题。处理程序保持不变

handle_info({deallocate_me,UUID,Pid},#state {dict = Uuid2Pid} = State) - >     NewDict = dict:erase(UUID,Uuid2Pid),     主管:terminate_child(fs_outbound_extn_sup,Pid),     error_logger:info_msg(“Successfully deallocated~p”,[UUID]),     {noreply,State#state {dict = NewDict}}。

但现在我仍然得到:

** Reason for termination == 
** {bad_return_value,{deallocate_me,"49d9f7cb-62d3-4c3f-abf1-a19848967a9a",
                                    <0.50.0>}}

1 个答案:

答案 0 :(得分:0)

对我来说似乎

fs_outbound_controller:deallocate_me(UUID, self());

被称为handle_call/3handle_cast/2handle_info/2内的最后一个语句。如您所知,这些期待{reply, ...}{noreply, ...}{stop, ...}之类的内容。

请注意,gen_server:cast/2始终返回okServerPid ! Message始终返回Message本身。这就是您第一次被告知{bad_return_value, ok}而第二次{bad_return_value, MessageSent}时的原因。

在你的情况下,我会坚持使用gen_server:cast方式,并在错误的通话后立即输入正确的返回值:

fs_outbound_controller:deallocate_me(UUID, self()),
{noreply, State}; %% strongly depends on what your logic there is