Dynamic Supervised GenServers에 대한 참고 사항

9559 단어 todayilearnedelixir
참조는 this lesson 입니다. "이름"을 사용하면 GenServer를 "즉시"시작할 수 있습니다. 예를 들어:
Order.start_link(name: :a)
모든 클라이언트 함수는 다음 이름을 사용하여 호출됩니다. Order.deliver(:a)
defmodule Order do
  use GenServer

  def start_link(name: name) do
    {:ok, _pid} = GenServer.start_link(__MODULE__, name, name: name)
  end

  def show(name), do: GenServer.call(name, :show)

  def add(name, value), do: GenServer.call(name, {:add, value})

  def deliver(name), do: GenServer.cast(name, :deliver)



  def init(name = _state), do: {:ok, {name, :init, 0}}

  def handle_call(:show, _from, {_n, step, value} = state) do
    {:reply, {step, value}, state}
  end

  [... server callbacks...]
end


이름을 지정하려면 원자를 사용해야 합니다(또는 해당 PID 또는 global 이름을 사용하거나 :via 사용). docs on name registration이 설명합니다.

"이름"이 결정되면 이 프로세스를 감독하려고 합니다.
레지스트리와 동적 감독자를 사용해야 합니다. 이 감독자와 이 레지스트리는 여기 애플리케이션 모듈에서 인스턴스화된 감독 트리에 있습니다.

use Application

def start(_, _) do
    [
      {Registry, keys: :unique, name: MyRegistry},
      {DynamicSupervisor, name: MyDynSup}
    ]
    |> Supervisor.start_link(opts)
end

:via 전략을 사용하고 이전 "주문"모듈을 감독합니다. 각각의 새 프로세스는 start_child로 "수동으로"시작됩니다.
클라이언트 함수의 "name"인수에 대한 참조가 아래와 같이 "via_tuple(name)"으로 대체되는 수정된 클라이언트 함수로 새 모듈을 만듭니다. 새 모듈은 GenServer를 래핑합니다. DynOrder.new("a")로 새로운 동적 감독 GenServer를 시작합니다.
서버 콜백은 이전 모듈에 남아 있습니다.

defmodule DynOrder do

  defp via_tuple(name) do
    {:via, Registry, {MyRegistry, name}}
  end

  def new(name) do
    DynamicSupervisor.start_child(
      DynSup,
      {Order, [name: via_tuple(name)]}
    )
  end


  def show(name), do: via_tuple(name) |> Order.show()

  def add(name, value), do: via_tuple(name) |> Order.add(value)

  def deliver(name), do: via_tuple(name) |> Order.deliver()
end


이제 프로그래밍 방식으로 이름을 할당하고 많은 동시 감독 프로세스를 실행할 수 있습니다.

Enum.each(1..100, fn i -> 
   DynOrder.new("a-#{i}");
   DynOrder.deliver("a_#{i}")
end)



partition supervisor 으로 한 단계 더 나아갈 수도 있습니다.

좋은 웹페이지 즐겨찾기