我是elixir / phoenix的新手。我正在开发一个以前创建的具有多个存储库的应用程序,今天我看到一个让我想知道配置意味着什么的例子
我想我不知道如何搜索这就是我无法在文档上找到正确答案的原因
首先,我正在使用的应用程序有类似
的内容defmodule RestApi do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
supervisor(RestApi.Endpoint, []),
supervisor(RestApi.Repo, []),]),
supervisor(RestApi.OtherRepo, []),]),
]
opts = [strategy: :one_for_one, name: RestApi.Supervisor]
Supervisor.start_link(children, opts)
end
def config_change(changed, _new, removed) do
RestApi.Endpoint.config_change(changed, removed)
:ok
end
end
他们使用函数Supervisor.Spec.supervisor/3来启动/管理所有内容
后来我找到了一个例子
defmodule RestApi do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
supervisor(RestApi.Endpoint, []),
worker(RestApi.Repo, []),
]
opts = [strategy: :one_for_one, name: RestApi.Supervisor]
Supervisor.start_link(children, opts)
end
def config_change(changed, _new, removed) do
RestApi.Endpoint.config_change(changed, removed)
:ok
end
end
<{3>} example他们使用Supervisor.Spec.worker/3来启动/管理回购
答案 0 :(得分:9)
认为主管是监督树中的一个分支,而工人是一个叶子。
每个supervisor
都是worker
,而每个worker
都不是supervisor
。尽管supervisor
具有一系列专门用于管理子流程的功能,但与通用gen_server
相比,它实际上对生产力的影响非常小。摘自OTP design principles的摘录解释了supervisor
应该是什么:
主管负责启动,停止和监控其子流程。主管的基本思想是通过在必要时重新启动它们来保持子进程的活跃 要启动和监视的子进程由子规范列表指定。子进程按此列表指定的顺序启动,并以相反的顺序终止。
除此之外,它是“worker
。”
也就是说,有一条易于采用的经验法则:当流程管理子流程时,它是supervisor
,否则为worker
。
在上述例子中:
children = [
supervisor(RestApi.Endpoint, []),
worker(RestApi.Repo, []),
]
RestApi.Endpoint
管理子流程,而RestApi.Repo
则不会。除此之外,两者都是普通的好gen_server
s。
答案 1 :(得分:2)
您使用supervisor
启动作为主管的流程,使用worker
启动工作人员(基本上不是主管的任何事情)。您可以在Supervisor和Supervisor.Spec模块文档中找到更多相关信息。
似乎版本之间的流程类型发生了变化,或者其中一个示例有错误,但我认为它应该是一个工作流程,但我会查看Ecto文档。
至于它如何影响应用程序,除了记录子进程的类型之外没有其他有意义的区别 - 它在Erlang中实际上是可选的。主管管理他们自己的一套子流程,形成一个监督树。您可以使用它来隔离崩溃对该树的子分支的影响,以便应用程序的不相关部分可以在其主管重新启动故障分支时继续运行。这是语言中容错的来源,也是OTP的基本构建块。
工作者是迄今为止最常见的进程类型,他们不管理子进程,并且在出现问题时被设计为崩溃并由其主管重新启动,其想法是从一个干净的已知状态重新开始。太多故障导致父管理程序崩溃,而管理程序又由其管理员重新启动 - 如果这会冒泡到应用程序的顶级管理程序,则应用程序将崩溃。
希望这有助于:)