자동으로 감시 트리를 시작하면 교착 상태 문제가 발생합니다. 하나의 GenServer의 초기 상태는 트리에있는 다른 감독자의 하위 작업자입니다.Elixir - 다른 여러 GenServer pids의 초기 상태가있는 GenServer
감독자 및 근로자 : 그 근로자의 PID의 상태
defmodule Parallel.Worker.Supervisor do
import Supervisor.Spec
def start_link do
# Start up a worker for each core
schedulers = :erlang.system_info(:schedulers)
children = Enum.map(1..schedulers,
&(worker(Parallel.Worker.Server, [], id: "Parallel.Worker#{&1}")))
opts = [strategy: :one_for_one, name: Parallel.Worker.Supervisor]
Supervisor.start_link(children, opts)
end
def workers do
Process.whereis(Parallel.Supervisor)
|> Supervisor.which_children
|> Enum.reduce [], fn
{_name, pid, :worker, _module}, acc -> [{make_ref, pid} | acc]
_, acc -> acc
end
end
end
GenServer :
defmodule Parallel.Process.Server do
use GenServer
def start_link do
GenServer.start_link(__MODULE__, workers: [Parallel.Worker.Supervisor.workers])
end
end
마지막 줄에서 볼 수 있듯이, 내가 전화하고 "Parallel.Worker 여기 코드는 .Supervisor.workers "이것은 트리에서 초기화를 기다리는 것을 차단하는 것으로 보입니다.이 메소드는이 메소드가 반환 될 때까지 완료되지 않습니다. PID를 초기 GenServer 상태로 어떻게 감독 할 수 있습니까?
UPDATE :
나는 내가 더 배울 수 있도록 (이 소스에서 볼 수있는 좋은 제안이 비록) poolboy을 사용하지 싶어. 저는 특별히 아무것도하지 않으려 고합니다. 직원은 인수가있는 전달 된 함수를 처리하기 만합니다. Heres the Worker GenServer :
defmodule Parallel.Worker do
use GenServer
require Logger
def start_link(state) do
GenServer.start_link(__MODULE__, state, [])
end
def init(state) do
{:ok, state}
end
# Using cast to be async as the job could take longer than the default 5 seconds,
# Don't want client blocked on waiting for job to complete
def handle_cast({:execute, fun, args, return_pid, job_ref}, state) do
Logger.debug fn()-> "#{inspect self}: Recevied job with args: #{inspect args} for job #{inspect job_ref} to return to #{inspect return_pid}" end
send(return_pid, {job_ref, apply(fun, args), self})
{:noreply, state}
end
end
아마도 작업자 pid를 명시 적으로 전달하지 않고 응용 프로그램을 다시 아키텍처해야합니다. 지금 여기서 뭘하려고하는거야? –
아마도 Poolboy와 같은 풀링 라이브러리를 찾고 계십니까? 이 기사를 확인하십시오 : http://hashnuke.com/2013/10/03/managing-processes-with-poolboy-in-elixir.html –