プロセスの生成は簡単ですが、その状態や振る舞いの管理はとても複雑になることがあります。Agentモジュールは、Elixirのプロセスで共有状態を管理しやすくするための抽象化です。
Agentモジュールの関数を使うときは、エージェント関連の関数を1つのモジュールにまとめるのが慣習です。
# A simple use of agent processes to represent a counter
defmodule Counter do
def start_link(initial_value) do
Agent.start(fn -> initial_value end)
end
def value(pid) do
Agent.get(pid, & &1)
end
def increment(pid) do
Agent.update(pid, &(&1 + 1))
end
end
Agentモジュールを使うか、そもそも複数のプロセスを使うかは、データでモデル化したい関係性によって決まります。_エージェントプロセス_は、複数のプロセスから共有状態を使う必要があるときに役立ちます。
状態を保持するために別のプロセスを使わず、関数内のプロセス内の変数を使うほうがよい場合もよくあります。また、それらをグローバル変数のように何も考えずに扱うのは避けるべきです。他のプロセスから操作されて競合状態を生んだり、追跡できないエラーの原因になったりする可能性があるからです。
_エージェントプロセス_を使う場合は、シンプルな状態を保持することを目標にし、_エージェントプロセス_への呼び出しはモジュール内にまとめて整理しましょう。
時間のかかる処理を別のプロセスで行う必要がある場合は、タスクプロセス(Taskを使用)を検討しましょう。あるプロセスが状態を保持し、さらに振る舞いを実行する必要があると判断した場合は、GenServerプロセス(GenServerを使用)を検討しましょう。