最近在开发过程中遇到一个问题,大概是这样的,原先一个worker进程,现在要改成可以随时去掉,也可以随时在重启,这个进程的supervisor是one_for_one类型的,如果不改变supervisor的类型(代码里面很多都是用这个supervisor的,改supervisor不好),这样就引发了一个问题,实验证明如下:
如果一个supervisor是simple_one_for_one,你无论使用多少次supervisor:start_child(Super, Arg)都不会有问题,但是如果是其他的,比如one_for_one,使用supervisor:start_child(Super, {ID, {M, F, A}, Restart, ShutDown, Type, Args}),只要ID一样第二次就报错了,[{error,{already_started,<0.844.0>}}]。其实很好理解one_for_one的情况下,ChildID什么的都是自己定好的,如果相同的ChildID,spervisor不会接受。simple_one_for_one什么的是动态加载的,ID什么的应该他内部有方法解决了。
既然如此那么解决方法也就有了,弄一个simple_one_for_one的supervisor,那个需要随时重启和去掉的worker进程就挂载在这个新的supervisor下,这样就能解决ChildID冲突了。如果偷懒不想新弄一个supevisor,那就在start这个worker前,加上supervisor:delete_child(Super, ChildID)。这个东西的作用就是,如果ChildID的进程是running或者restart的,那就会返回错误;如果ChildID的进程是死的,那就会释放这个ChildID给下次start_child时候用。
还有一个需要注意的是,既然要随时去掉和重启,那么start_child的参数什么的要注意了,设置重启策略为不重启或者其他,具体参数解释:传送门http://blog.youkuaiyun.com/xum2008/article/details/9288411 ;
如果一个supervisor是simple_one_for_one,你无论使用多少次supervisor:start_child(Super, Arg)都不会有问题,但是如果是其他的,比如one_for_one,使用supervisor:start_child(Super, {ID, {M, F, A}, Restart, ShutDown, Type, Args}),只要ID一样第二次就报错了,[{error,{already_started,<0.844.0>}}]。其实很好理解one_for_one的情况下,ChildID什么的都是自己定好的,如果相同的ChildID,spervisor不会接受。simple_one_for_one什么的是动态加载的,ID什么的应该他内部有方法解决了。
既然如此那么解决方法也就有了,弄一个simple_one_for_one的supervisor,那个需要随时重启和去掉的worker进程就挂载在这个新的supervisor下,这样就能解决ChildID冲突了。如果偷懒不想新弄一个supevisor,那就在start这个worker前,加上supervisor:delete_child(Super, ChildID)。这个东西的作用就是,如果ChildID的进程是running或者restart的,那就会返回错误;如果ChildID的进程是死的,那就会释放这个ChildID给下次start_child时候用。
还有一个需要注意的是,既然要随时去掉和重启,那么start_child的参数什么的要注意了,设置重启策略为不重启或者其他,具体参数解释:传送门http://blog.youkuaiyun.com/xum2008/article/details/9288411 ;
在Erlang开发中,遇到一个需求是使worker进程能够动态添加和重启。由于原有的supervisor为one_for_one类型,导致相同ID的进程无法重复启动。文章介绍了问题的原因和解决方案,包括利用simple_one_for_one类型的supervisor来解决ChildID冲突,或者在启动前删除旧的ChildID。此外,强调了start_child参数的设置,特别是重启策略的选择,以实现进程的灵活管理。
1219

被折叠的 条评论
为什么被折叠?



