Agentとは
Agentとは単一の状態を保持する仕組みである。
GenServerより状態管理が簡略化されおり、また値を取得する方法が提供されている。(Agent.get()
)
高可用性を求める場合には、代わりにGenServerを使用すること。
基本的な使い方
Agentはプロセスと同じように生成する。
{:ok, agent} = Agent.start_link(fn -> 初期状態 end)
生成されたAgentに対して更新や値の取得は、下記のように行う。
# 更新
Agent.update(agent, fn 状態 -> 状態の更新処理 end)
# 値の取得
Agent.get(agent, fn 状態 -> 出力 end)
生成したAgentを終了させるには、以下を記述する。
Agent.stop(agent)
Agentをスーパーバイザーに追加する
Agentもプロセスなので、スーパーバイザーの監視ツリーに追加することができる。
ここでは実際にAgentのモジュールを記述して、監視ツリーに追加してみる。
モジュール
Agentモジュールは、大体以下の要点を考慮して記述を行うと良い。
-
use Agent
の記述 -
start_link()
関数の実装
defmodule 省略.SampleAgent do
use Agent
def start_link(init_status) do
Agent.start_link(fn -> init_status end, name: __MODULE__)
end
# 取得する値別に関数を作成するとよい
def get() do
Agent.get(__MODULE__, fn status -> 値を取得する処理 end)
end
end
スーパーバイザー
スーパーバイザーの詳しい解説はこちら。
以下のように記述して子プロセスのリストに追加する。
children = [
{省略.SampleAgent, %{name: "Takashi", age: 42}}
]
上記の記述によりAgentをスーパーバイザーの監視ツリーに追加すると、
Agentが終了したとき再起動するようになった。
なお、当たり前だがAgent.stop()
によって、Agentは終了しなくなる。
結論
AgentはGenServerより簡略化された状態管理の仕組み。
Phoenixを起動しながら実行するサーバーサイドの処理で使用する
状態を、個別に管理、状態を取得する、というような使い方ができる。
高可用性が求められる場合はGenServerを使用すること。(と書いてあった)