GenServer
GenServer
Supervisorによって監視が可能
同期・非同期呼び出しを処理可能
GenServer(及びプロセス)はコードの構造化のために使うべきではない(moduleや関数を使って構造化すべき)
チートシート
説明用
code:elixir
defmodule Queue do
use GenServer
def start_link(default) when is_list(default) do
GenServer.start_link(__MODULE__, default)
end
def enqueue(pid, element) do
# 説明のためcastを使っているが、本来この処理にはcallを使うべき
GenServer.cast(pid, {:enqueue, element})
end
def dequeue(pid) do
GenServer.call(pid, :dequeue)
end
@impl true
def init(queue) do
{:ok, queue}
end
@impl true
{:reply, head, tail}
end
@impl true
def handle_cast({:enqueue, element}, queue) do
end
end
{:ok, pid} = Queue.start_link(:hello) Queue.enqueue(pid, :world) # => :ok
Queue.enqueue(pid, :hoge) # => :ok
Queue.dequeue(pid) # => :hello
Queue.dequeue(pid) # => :world
Queue.dequeue(pid) # => :hoge
メッセージ
call - 同期的
cast - 非同期
info - Kernel.send/2やProcess.monitor等により送信されるメッセージ
API
GenServer.start_link/2
GenServerビヘイビアを実装したモジュールと初期値
GenServer.call/3
callメッセージを送信
GenServer.cast/2
castメッセージを送信
GenServerビヘイビア
init/1
実装が必須
handle_call/3
handle_cast/2
handle_info/2
Kernel.send/2等で送信された通常のメッセージを処理したいときに実装する
supervisorの監視下で動作させる
※use GenServerを実行すると、自動的にchild_spec/1が定義される
code:elixir
children = [{Queue, :hoge}] Supervisor.start_link(children, strategy: :one_for_all)
参考