我有一个由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>}}
答案 0 :(得分:0)
对我来说似乎
fs_outbound_controller:deallocate_me(UUID, self());
被称为handle_call/3
,handle_cast/2
或handle_info/2
内的最后一个语句。如您所知,这些期待{reply, ...}
,{noreply, ...}
或{stop, ...}
之类的内容。
请注意,gen_server:cast/2
始终返回ok
,ServerPid ! 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