在我的Erlang/OTP应用程序中,我有一个one_for_all主管(sup),有几个孩子.其中一个子节点(带有gen_server行为的child1)应该能够向另一个节点发送消息(带有supervisor行为的child2).当然,我可以注册它,但是用多余的名字堵塞全球范围似乎不是一个好主意.
从而使这种相互作用可能的唯一途径是提供child1与的PID 的child2.说到做到.有supervisor:wich_children/1适当的功能调用.刚好路过燮的PID为参数chidl1,称which_children在child1:init,和...得到一个僵局.SUP等待child1开始,child1等待燮为孩子的描述:
init(SupPid) ->
Descriptions = supervisor:which_children(SupPid),
... .
Run Code Online (Sandbox Code Playgroud)
这可以通过以下方法解决:
init(SupPid) ->
gen_server:cast(self(), initialize),
... .
handle_cast(initialize, State) ->
Descriptions = supervisor:which_children(SupPid),
... % Generating new state containing desired pid
{noreply, NewState}.
Run Code Online (Sandbox Code Playgroud)
但是,我对此解决方案并不满意.
问题是:根据OTP设计原则,监管树成员之间最常见的交互方式是什么?
小智 5
当然,你还不能向主管询问它的孩子,而它还没有启动它们:)
实际上,注册(在本地,使用erlang:register())并不是一个坏主意.此外,如果在child1中处理原始pid,你应该手动设置child2 pid的监控,以便能够对可能的崩溃等作出反应,但是注册后你就可以直接通过名字来询问它.
如果没有注册,您可以推迟通知孩子直到主管:start_link被调用:
start_link() ->
R=supervisor:start_link({local, ?SERVER}, ?MODULE, []),
%% Here supervisor is started so you can notify its children
R.
Run Code Online (Sandbox Code Playgroud)