Best-effort OTP监管

Best-effort OTP supervision

我想做的是改变我的主管,尽最大努力保持 children 运行,但如果他们的崩溃率超过强度,就放弃。这样 children 的剩余部分将保留 运行。但是,对于现有的主管配置,这似乎是不可能的,所以看起来我唯一的选择可能是实现我自己的主管,这样我就可以让它在收到 EXIT.[=12 时以这种方式运行=]

有没有一种方法可以在不编写自己的主管的情况下实现这样的自定义 OTP 主管行为?

你不能"extend" Supervisor 添加不同的监督行为,但你也不必从头开始。 :supervisor 模块本身是在 :gen_server 之上实现的,所以如果你发现自己需要一些,我会参考 :supervisor 的源代码(你可以找到 here)海关监管行为的种类;它将为您提供构建基础,以避免您可能遇到的一些陷阱。

一旦我对您的用例有了更好的了解,我就可以扩展我对替代解决方案的回答。正如我在评论中提到的,在我看来,您可能在 init/1 过程中做了一些容易失败的事情; init/1 不是处理那些事情的地方,因为如果那个动作暂时不可能成功,你几乎肯定会破坏主管的最大重启强度。

例如,假设您有一个与数据库对话并需要数据库连接的进程;您不想在 init/1 期间尝试连接到数据库。相反,您应该获取连接 post-init(可能在首次使用时,或者通过立即向使用 Process.send_after(self(), :connect, 0) 的进程发送 post-init 消息),如果连接失败, return 在您尝试重新建立连接时向任何呼叫者发送类似 {:error, :database_unavailable} 的内容。使用这种方法进行设计将使您的监督树保持稳定,而是将如何处理故障的决定推给可能对故障如何影响他们有更好信息的客户(即,他们是否应该重试操作,return 给他们的调用者一个错误,异常退出等)

在我看来你想要的是每个 child 的单独主管,负责保持它的活动达到极限,正如你所说,并且作为上面的层有一个主管( one-for-one or simple-one-for-one) 其 children 被标记为临时的,因此当其中一个放弃时,其余的留在 运行.

你也可以用director,解决这个问题更灵活。