我有许多受监督的组件可以作为单独的应用程序单独使用。但是我想将它们级联起来,使得一个组件中的worker中的调用或事件以倒置的树状结构向下启动下一个组件。
1)我可以将每个组件打包成单独的应用程序吗? 2)如果是这样,我如何编写调用代码来启动子应用程序? 3)或者我是否需要完全做其他事情,如果是,那又是什么?
注意:我仍在努力掌握监督树。应用程序后的事件链:start(Mod)仍然没有很好地融入我的脑海。
非常感谢,
LRP
答案 0 :(得分:1)
监督树和应用程序是复杂的Erlang / OTP概念。它们都记录在OTP Design Principles User's Guide中,特别是在:
中监督树不是依赖树,不应该这样设计。相反,应根据所需的崩溃行为以及所需的启动顺序来定义监督树。提醒一下,运行时间足够长的每个进程都必须在监督树中。
应用程序是可以启动和停止的可重用组件。应用程序可能依赖于其他应用程但是,应用程序应在启动时启动,不在事件发生时启动。
当给定事件发生时可以启动进程。如果要监督此类流程,只需在事件发生时在其主管上调用supervisor:start_child/2
。这将启动该过程,并将其插入监督树中。您通常会使用最初没有孩子的Simple-one-for-one supervisor。
因此:
您可以将组件打包为单独的应用程序。在这种情况下,您将在每个应用程序的app(4)文件中声明应用程序的依赖关系。然后,应用程序只能以正确的顺序启动,无论是使用启动脚本还是以application:start/1
交互式启动。
您可以将所有组件打包在一个应用程序中,让工作进程使用supervisor:start_child/2
启动其他工作进程。
您可以将组件打包为单独的应用程序,并在一个应用程序中将工作进程启动到另一个应用程序中的进程。在这种情况下,最好的方法是在目标应用程序中定义一个将调用supervisor:start_child/2
本身的模块,因为应用程序应该有干净的API。
当您有工作进程(父级)启动其他工作进程(子级)时,您可能将链接这些进程。使用link/1
实现链接。链接是对称的,通常是从父节点建立的,因为父节点知道子节点的pid。如果父进程异常退出,则该子进程将被终止,并且相互终止。
链接是处理崩溃的最常用方法,例如,如果父级不再存在,则应终止子级。链接实际上是OTP监督的基础。在工作进程之间添加链接表明设计监督树实际上很困难。实际上,对于链接,如果一个进程崩溃,您将有两个进程终止,但是,您可能不希望主管重新启动子进程,因为主管重新启动的子进程将不会被知道(或链接)到管理员重启的父进程。
如果父母在孩子正常退出时终止,那么这是一个完全不同的设计。您可以让孩子向父母发送消息(例如,返回结果)或父母监视孩子。
最后,父进程可以终止子进程。如果孩子受到监督,请使用supervisor:terminate_child/2
。否则,您只需向子进程发送退出信号即可。在任何一种情况下,您都需要取消子进程的链接以避免退出父进程。
links中记录了monitors和Erlang Reference Manual User's Guide。您可能会试图陷入退出,而不是监视器,这在the guide中有所解释。但是,实现此功能的手册页(process_flag/2)具体为:
应用程序进程通常不会陷阱退出。
这是典型的OTP设计智慧,在文档中随处可见。请改用监视器或简单消息。