【问题标题】:Erlang supervision and applicationsErlang 监督与应用
【发布时间】:2013-08-10 03:02:54
【问题描述】:

我有许多可以独立作为单独应用程序的受监督组件。但我想将它们级联起来,以便一个组件中的工作人员中的调用或事件以倒置的树状结构开始下一个组件。

1) 我可以将这些组件中的每一个打包为单独的应用程序吗? 2)如果是这样,我该如何编写调用代码来启动子应用程序? 3) 还是我需要完全做其他事情,如果需要,怎么办?

注意:我仍在努力掌握监督树。 application:start(Mod) 之后的事件链在我的脑海中仍然没有得到很好的理解。

非常感谢,

LRP

【问题讨论】:

    标签: erlang erlang-supervisor


    【解决方案1】:

    监督树应用程序是复杂的 Erlang/OTP 概念。它们都记录在OTP Design Principles User's Guide 中,特别是:

    监督树不是依赖树,不应这样设计。相反,应根据所需的崩溃行为以及所需的启动顺序来定义监督树。提醒一下,每个运行时间足够长的进程都必须在监督树中。

    应用程序是可以启动和停止的可重用组件。应用程序可以依赖于其他应用程序。但是,应用程序应在启动时启动,而不是在事件发生时启动

    可以在给定事件发生时启动进程。如果此类过程应受到监督,只需在事件发生时在其主管上调用supervisor:start_child/2。这将启动该过程并将其插入到监督树中。您通常会使用 Simple-one-for-one supervisor,它最初没有孩子。

    因此:

    1. 您可以将组件打包为单独的应用程序。在这种情况下,您将在每个应用程序的app(4) 文件中声明应用程序的依赖关系。然后只能以正确的顺序启动应用程序,或者使用启动脚本或与application:start/1 交互。

    2. 您可以将所有组件打包在一个应用程序中,并让工作进程使用supervisor:start_child/2 启动其他工作进程。

    3. 您可以将组件打包为单独的应用程序,并让工作进程在一个应用程序中启动另一个应用程序中的进程。在这种情况下,最好在目标应用程序中定义一个模块来调用supervisor:start_child/2,因为应用程序应该有干净的 API。

    当您有工作进程(父进程)启动其他工作进程(子进程)时,您可能将链接这些进程。使用link/1 实现链接。链接是对称的,通常是从父级建立的,因为父级知道子级的 pid。如果父进程异常退出,子进程会被终止,反之亦然。

    链接是处理崩溃的最常用方法,例如,如果父级不再存在,则应终止子级。链接实际上是 OTP 监管的基础。在工作进程之间添加链接表明设计监督树实际上很困难。实际上,使用链接,如果一个进程崩溃,您将终止两个进程,但是,您可能不希望主管重新启动子进程,因为主管重新启动的子进程将不知道(或链接)到主管重新启动父进程。

    如果父级在子级正常退出时终止,那么这是一个完全不同的设计。您可以让孩子向父母发送消息(例如返回结果)或父母监控孩子。

    最后,父进程可以终止子进程。如果孩子受到监督,请使用supervisor:terminate_child/2。否则,您可以简单地向子进程发送退出信号。无论哪种情况,您都需要取消子进程的链接以避免父进程退出。

    linksmonitors 都记录在 Erlang Reference Manual User's Guide 中。除了监视器,您可能会想要捕获出口,the guide 中对此进行了解释。然而,实现这一点的函数的手册页(process_flag/2)具体写着:

    应用程序进程通常不应捕获出口。

    这是典型的 OTP 设计智慧,在文档中到处传播。请改用监视器或简单消息。

    【讨论】:

    • 非常感谢,保罗。是的,当我阅读参考资料时,它们看起来很简单,但是当我尝试将它们付诸实践时……无论如何,我有组件 A、B、C……A 有许多由简单的一对一创建的流程主管,如 B 和 C 等。A 中的每个进程都有一个选择设备,该设备使该进程的用户能够选择 B 中的功能,从而启动 B 拥有的进程,该进程在 A 中的启动进程终止时终止。也许您的回复中的选项涵盖了这种情况。但是,遗憾的是,我仍然不清楚。再次感谢 LRP
    • 假设,我可以补充一下,我们有很多用户,每个用户都遍历他/她自己的树实例。 (我开始怀疑这个案例比描述更难。)谢谢,L。
    • 您需要选项 2 或 3。此处与应用程序拆分无关。如果“A 中的进程终止时”是指崩溃,则需要链接这些进程。如果您的意思是优雅地终止,那么来自 A 的进程只需要终止来自 B 的子进程。我相应地更新了答案。
    • 谢谢你,保罗。我会尝试一些 Tinkertoy 代码,看看我是否理解。
    猜你喜欢
    • 2011-05-24
    • 2016-02-12
    • 2011-08-07
    • 2012-01-13
    • 1970-01-01
    • 2014-09-12
    • 2023-03-02
    • 2015-05-16
    • 2013-09-16
    相关资源
    最近更新 更多