Home - noetl/worker GitHub Wiki
noetl-worker
NATS is removed from the worker's command path (2026-08-01). Commands come from the EHDB bus; the pool comes from
NOETL_FEED_FILTER_SUBJECT. See deployment-specification and
- Shard election (C2) โ minting the fencing token: lease over
coordination.k8s.io/v1, per-process identity, and whytoken_validis notholds_lease.
The NoETL worker pool: a NATS-driven pull-model executable that consumes command events from JetStream and runs them against the noetl-tools registry.
What the worker is
A stateless atomic compute block, in ยง H.10's terms: claim a command from NATS, hydrate inputs from the per-execution context, execute one tool, write outputs back to the event log via the Python control plane, release the slot.
- Stateless โ no per-tenant resident state between commands.
- Pull model โ subscribes to a JetStream durable consumer; no recursion.
- Replaceable โ multiple workers process the same queue; KEDA scales them on real consumer lag.
The worker's twin is the noetl CLI: same tool dispatch surface, same execution semantics, but the CLI uses a recursive tree walker for local YAML execution where the worker uses a flat pull loop. See ยง H.10 for why the two control loops stay separate.
Crate dependency graph
noetl-worker (this crate)
โโโ noetl-tools = "2.16" # tool registry (rhai, shell, http, duckdb, postgres,
โ # result_fetch, nats, mcp, ...)
โโโ noetl-executor = "0.3" # shared utilities + types (condition eval, event envelope,
โ # tool dispatch bridge; ships from the noetl/cli workspace)
โโโ async-nats = "0.38" # JetStream consumer
โโโ reqwest = "0.12" # HTTP client for the control plane
โโโ tokio = "1" # async runtime
noetl-executor and noetl-tools are the shared surface: both the CLI and the worker call into them. The worker keeps its NATS pull loop + control-plane HTTP client + pull-loop control flow (case evaluator, command dispatcher) local because those are worker-specific shapes per ยง H.10.
Module layout
| Module | Purpose |
|---|---|
worker |
Main worker loop โ claim, dispatch, ack/nack. |
config |
Runtime config (NATS URL, server URL, worker id, stream/consumer names). |
nats::subscriber |
JetStream consumer + CommandNotification envelope. |
client::control_plane |
HTTP client to the Python control plane โ fetch commands, emit events, read/write vars. |
events::emitter |
EventEmitter with retry logic over ControlPlaneClient.emit_event. |
executor::command |
CommandExecutor โ runs one tool, evaluates cases, emits lifecycle events. |
executor::case_evaluator |
Worker-specific pull-loop control flow (Case / CaseAction / CaseResult / CaseEvaluator). Condition primitives (Operator, Condition, evaluate_structured_condition) delegate to noetl_executor::condition as of R-1.2 PR-2c. |
Pages
- noetl-executor adoption โ what surfaces the worker imports from
noetl-executor, what stays local, R-1.x landing history (parallels the cli's executor-crate-architecture page from the consumer side). - Release pipeline โ semantic-release โ
release-workerflow; the GitHub-Actions safeguard gotcha and the workaround. - Worker credentials โ
NOETL_KEYCHAIN_ENV_VARSallow-list (5.7.0+, noetl/ai-meta#34) that lifts platform-mounted Secret env vars into the in-process keychain map for playbookctx.get_secret(alias)lookups. - nats and mcp tool kinds โ playbook config shape, credential wiring, and dispatch path for the
nats(2.15.0) andmcp(2.16.0) tool kinds picked up by thenoetl-toolsbump in this version. - cmdbus-writer: tier service and the engine lock โ the writer role (
NOETL_COMMAND_BUS_HOST/NOETL_EVENT_BUS_HOST): why the:9102lag endpoint shares the engine lock with tier reads, thehealth-vs-read_executionpairing that tells contention from a wedge, and why the writer's TCP-only probes cannot see a stall. - Deployment specification โ durable reference for deploying noetl-worker: runtime contract, NATS layout, KEDA scaling, full env-var catalogue with rationale, snowflake node-id derivation, secrets handling, kind-validation procedure. Updated in lockstep with code per
wiki-maintenance.md.
Distribution channels
- Crates.io:
noetl-worker - Container image: GHCR/GCR (recommended primary runtime channel)
- Cloud Build: for image builds + GKE deploy
Related
- noetl-executor crate architecture โ the shared crate's design + R-1.x sub-PR history.
- ยง H.10 โ tree walker vs pull model
- Appendix H โ Rust migration roadmap
- noetl/tools wiki โ tool registry the worker dispatches through.
- noetl/server wiki โ Python control plane the worker emits events to + fetches commands from.