我有一个elixir应用程序,带有一个简单的1对1主管,其子女为1个1个主管,有多个工人。像这样:
------------------
| SupSup (s141) |
------------------
|
|-------------------------------------- ...
| |
------------------ ------------------
| Sup (141) | | Sup (141) | ...
------------------ ------------------
| | | |
---------- ----------
| Worker | ... | Worker | ... ...
---------- ----------
一些工作者将Erlang端口(使用Porcelain
创建)到外部进程。应用程序需要在树的Sup
级别停止子树。执行此操作的代码(在Worker
中运行)为spawn(fn() -> Supervisor.terminate_child(Sup, pid) end)
,其中pid
是工作人员的代理商(通过:gproc
查找)
在Fedora 24上,使用Supervisor.terminate_child()
会导致Erlang VM崩溃:
erl_child_setup closed
Crash dump is being written to: erl_crash.dump...done
在Ubuntu 16.04上,没有崩溃,子树按预期干净地退出。
为什么呢?
这是一个相当复杂的情况,因此粘贴整个应用程序是不合适的。我把所有需要的东西都复制了,包括在GitHub的murder_supervisor_test project中的Fedora 24崩溃转储。
编辑1:在Fedora上,环境是使用kerl和kiex构建的OTP 19.2 / Elixir 1.4.1。在Ubuntu上,Erlang和Elixir是19.1 / 1.4.0-1,并使用erlang-solution中的apt-get安装。
编辑2:删除Erlang& Ubuntu上的Elixir并使用kerl和kiex重新安装19.2 / 1.4.1并未改变结果:Ubuntu上没有VM崩溃。