ElGraph.Agent behaviour (ElGraph v0.3.0)

Copy Markdown View Source

장수명 에이전트 = 그래프 + 영속 상태 + 메일박스를 가진 GenServer (SPEC §5).

defmodule MyApp.ResearchAgent do
  use ElGraph.Agent

  @impl true
  def handle_signal(%ElGraph.Signal{data: data}, _context), do: {:run, data}

  @impl true
  def handle_result({:ok, state}, context), do: MyApp.notify(context.id, state)
end

{:ok, pid} = MyApp.ResearchAgent.start_link(graph: graph, id: "r1", checkpointer: cp)
ElGraph.Agent.send_signal(pid, %ElGraph.Signal{type: "task.assigned", data: %{...}})

실행은 GenServer 콜백 밖(별도 프로세스, nolink+monitor)에서 돌므로 에이전트는 실행 중에도 시그널을 받는다. 실행 중 도착한 {:run, _}은 큐에 들어가 직렬 처리된다. 체크포인터가 있으면 재시작 시 미완료 thread를 자동 재개한다 (crash-only, SPEC §5).

Summary

Types

콜백에 전달되는 컨텍스트: %{id:, opts:}

Callbacks

실행 결과를 받았을 때. 기본 구현은 no-op.

시그널을 받았을 때 — 그래프를 돌릴지(input과 함께) 무시할지 결정한다.

Functions

에이전트에 시그널을 보낸다 (비동기). 멱등 수신을 위해 전달 id를 보장한다.

에이전트 상태 요약: %{id:, running:, queued:} — 실행 중에도 응답한다.

Registry 기반 이름 — 동적 atom을 만들지 않는다 (SPEC §5).

Types

context()

@type context() :: %{id: term(), opts: keyword()}

콜백에 전달되는 컨텍스트: %{id:, opts:}

Callbacks

handle_result(result, context)

(optional)
@callback handle_result(ElGraph.Executor.result(), context()) :: :ok

실행 결과를 받았을 때. 기본 구현은 no-op.

handle_signal(t, context)

@callback handle_signal(ElGraph.Signal.t(), context()) :: {:run, map()} | :ignore

시그널을 받았을 때 — 그래프를 돌릴지(input과 함께) 무시할지 결정한다.

Functions

send_signal(server, signal)

@spec send_signal(GenServer.server(), ElGraph.Signal.t()) :: :ok

에이전트에 시그널을 보낸다 (비동기). 멱등 수신을 위해 전달 id를 보장한다.

status(server)

@spec status(GenServer.server()) :: %{
  id: term(),
  running: boolean(),
  queued: non_neg_integer()
}

에이전트 상태 요약: %{id:, running:, queued:} — 실행 중에도 응답한다.

via(registry, id)

@spec via(atom(), term()) :: {:via, Registry, {atom(), term()}}

Registry 기반 이름 — 동적 atom을 만들지 않는다 (SPEC §5).