노드 실행 컨텍스트. 모든 노드는 (state, ctx) 2-인자로 호출된다 (SPEC §3.2).
스트리밍 이벤트 방출, 협조적 취소 확인, 실행 메타데이터 접근의 통로다.
동적 인터럽트(interrupt/2)는 체크포인터와 함께 도입된다.
:assigns는 호출 단위(per-invocation)의 읽기 전용 컨텍스트로,
invoke(graph, input, assigns: %{...})로 주입되어 모든 노드의 ctx.assigns로 전달된다.
Summary
Functions
협조적 취소 확인 (SPEC §3.9). 긴 루프나 스트림 처리 중 주기적으로 호출하라.
스트리밍 이벤트를 구독자에게 방출한다.
동적 인터럽트 (SPEC §3.6). 실행을 중단하고 호출자에게 payload와 함께
{:interrupted, info}를 반환하게 한다.
부수효과 있는 계산(LLM/툴 호출 등)을 key로 메모이즈한다 (replay-safe durability).
Types
@type t() :: %ElGraph.Ctx{ assigns: map(), cancel_flag: :atomics.atomics_ref() | nil, event_sink: pid() | nil, interrupt_counter: :counters.counters_ref() | nil, node: atom(), resume_values: [term()], step: non_neg_integer(), task_cache: :ets.tid() | nil, thread_id: String.t() }
Functions
협조적 취소 확인 (SPEC §3.9). 긴 루프나 스트림 처리 중 주기적으로 호출하라.
ElGraph.Runner.cancel/2가 플래그를 세우면 true가 된다. 노드가 이를 무시하면
유예시간 후 brutal kill 된다.
스트리밍 이벤트를 구독자에게 방출한다.
invoke/3의 :event_sink 옵션으로 구독자 pid가 주어진 경우
{:el_graph_event, %{thread_id, step, node, event}} 메시지를 보낸다. 없으면 no-op.
동적 인터럽트 (SPEC §3.6). 실행을 중단하고 호출자에게 payload와 함께
{:interrupted, info}를 반환하게 한다.
ElGraph.resume(graph, resume: value)로 재개하면 노드가 처음부터 재실행되고,
이 함수는 이번에는 주입된 value를 반환한다. 한 노드 안의 여러 interrupt 호출은
호출 순서로 값과 매칭되므로 호출 순서는 결정적이어야 한다.
interrupt 이전의 부수효과는 재실행 시 중복된다 — interrupt는 노드 초반에 두라.
부수효과 있는 계산(LLM/툴 호출 등)을 key로 메모이즈한다 (replay-safe durability).
처음 호출되면 fun을 실행해 결과를 이 실행(run)의 task 캐시에 기록하고 반환한다.
이후 같은 노드에서 같은 key로 다시 호출하거나(재시도), 인터럽트/크래시 후 재개 시
노드가 처음부터 재실행될 때는 fun을 다시 돌리지 않고 캐시된 값을 돌려준다 —
LLM 호출 중복 비용·중복 부수효과를 막는다(Temporal Activity / LangGraph @task에 해당).
캐시는 체크포인트에 함께 영속되므로 재개(resume/resume_from)를 넘어 유효하다.
따라서 fun의 결과는 직렬화 가능해야 한다(pid/ref/port 금지 — 재개 시 무의미).
task_cache가 없는 컨텍스트(예: 실행기 밖에서 노드 직접 호출)에서는 그냥 fun을 실행한다.
answer = Ctx.memo(ctx, :classify, fn -> LLM.chat(...) end)