我有application.ex
看起来像这样:
defmodule Qtrain.Application do
use Application
def start(_type, _args) do
import Supervisor.Spec
children = [
supervisor(QtrainWeb.Endpoint, [], name: Qtrain.Supervisor),
supervisor(Qtrain.Requests, [], name: Qtrain.Requests)
]
Supervisor.start_link(children, strategy: :one_for_one)
end
def config_change(changed, _new, removed) do
QtrainWeb.Endpoint.config_change(changed, removed)
:ok
end
end
和requests.ex
看起来像这样:
defmodule Qtrain.Requests do
use GenServer
alias Qtrain.Requests.Document
def start_link do
GenServer.start_link(__MODULE__, %{})
end
def init(state) do
schedule_work()
{:ok, state}
end
def handle_info(:work, state) do
Document.start_link %{id: :one}
schedule_work()
{:noreply, state}
end
defp schedule_work() do
Process.send_after(self(), :work, 1 * 1000)
end
end
当我启动应用程序并运行:observer.start
时,我可以按预期使用:one
键查看该任务,但有两个错误。一,父母主管没有名字,尽管我在iex -S mix
中添加了一个和两个后续流程,如下所示:
Qtrain.Requests.Document.start_link %{id: :dammit}
不要导致在pid
下添加流程。
但是,它们会显示在进程选项卡中:
为什么我不能说那个主管?为什么新的流程不会出现呢?
答案 0 :(得分:3)
将name
选项传递给Supervisor.Spec.supervisor/3
对两种情况均无效(请检查observer
是否显示Endpoint
端点,而name
设置为Supervisor
。)实际上,甚至有no option name
understood。您应该在调用后续GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
中设置名称,以便将其显示在observer
中。
Whatever.start_link
不会使启动过程成为监督树的一部分。您应该明确地将其设置为具有Supervisor.start_child/2
的相应主管的子项(当父项是主管时,而不是您的情况),或者只是在相应的Document.start_link
进程内调用GenServer
,since
start_link
启动与当前流程关联的GenServer
流程 。
示例:
defmodule Qtrain.Requests do
# interface
def document!(id) do
GenServer.call(__MODULE__, {:document, id})
end
def handle_call({:document, id}, _from, state) do
Qtrain.Requests.Document.start_link %{id: id}
end
...
end
现在:
Qtrain.Requests.document! :damnit
会使Document
成为监督树的一部分,因为它将链接到Requests
进程。当您刚刚从控制台启动它时,它已链接到mix
进程。