mko*_*zun 5 erlang elixir erlang-otp erlang-supervisor
我试图从受监督的工人流程中终止整个监督树.这是我的监督树:
+--------------------------+
| |
+--------+ Sup1: Dynamic Supervisor +---------+
| | | |
| +-------------+------------+ |
| | |
| | |
v v v
+------------------+ +------------------+ +------------------+
| | | | | |
| Job1: Supervisor | | Job2: Supervisor | | Job3: Supervisor |
| | | | | |
+------------------+ +-+-------- +---+--+ +------------------+
| |
| |
| |
| |
v v
+-------------------+ +--------------+
| | | |
| Progress Monitor: | | Work: Worker |
| Worker | | |
| | +--------------+
+-------------------+
Run Code Online (Sandbox Code Playgroud)
流程生命周期:
Job通过以下方式开始:DynamicSupervisor.start_child(__MODULE__, spec)one_for_one) - > 2个工人Progress Monitor 工人知道什么时候完成给定的工作Progress Monitor工作人员通过调用以下方法尝试终止整个工作监督树:DynamicSupervisor.terminate_child(__MODULE__, pid)Progress Monitor预计会在terminate回调中执行清理步骤- 它会捕获退出信号问题和意见:
DynamicSupervisor.terminate_child 是一个阻塞调用,这意味着它等待所有子进程也终止,包括调用进程 - Progress MonitorProgress Monitor陷入僵局,无法终止.父监督发送:kill信号,不触发terminate回叫快速解决方法:
DynamicSupervisor.terminate_child从Progress Monitor工作人员异步调用:
spawn(fn -> DynamicSupervisor.terminate_child(__MODULE__, pid) end)
定义关闭策略Sup1: Dynamic Supervisor:
shutdown: 5_000
它将等待最多5秒的工作监督树终止,然后它将发送shutdown退出信号.这将确保terminate为Progress Monitor进程调用回调.
对他们两个都不满意.
问题:
只需在异步任务中调用它,Task.async(fn -> Process.exit(Sup1, :shutdown) end)它就会终止 Sup1,并且所有子任务都会关闭
编辑:
如果您需要更漂亮的解决方案,这取决于您还需要什么。在大多数情况下,我创建 Bootstrapper 工作程序来执行初始化和其他一些操作。您可以轻松添加其他功能。
因此,考虑到上面的内容,粗略地说,我会在上面添加一个层 ( AppSupervisor),另一个 DynamicSupervisor,以便它可以启动 Bootstrapper 并传递self()给它(或在本地名称下注册它以避免这种注入)。之后,在启动时,Bootstrap Worker 将启动 Sup1(您的动态管理程序)并等待其他消息,例如,:terminate_sup1将关闭Sup1进程。稍后,在下面的一些工作程序中,您可以Sup1通过将:terminate_sup1消息传递给引导程序来关闭。还有一扇门允许您在另一条消息发送到引导工作程序时重新启动 Sup1。
此外,如果您只需要关闭 Sup1,只需使用 Task 即可。但如果您需要控制,则将其放入单个工作进程中,该进程应在其启动或关闭时对其进行控制。
| 归档时间: |
|
| 查看次数: |
333 次 |
| 最近记录: |