-
Notifications
You must be signed in to change notification settings - Fork 0
event envelope
The wire format for POST /api/events — what workers (and CLI in distributed mode) send to ingest events into the event log.
pub struct EventRequest {
pub execution_id: String,
pub step: String,
#[serde(alias = "name")]
pub event_type: String,
#[serde(default, alias = "context")]
pub payload: serde_json::Value,
pub meta: Option<serde_json::Value>,
pub worker_id: Option<String>,
pub result_kind: String, // "data" | "ref" | "refs"
pub result_uri: Option<String>,
pub event_ids: Option<Vec<i64>>,
pub actionable: bool,
pub informative: bool,
// R-1.2 PR-EE-2 additions:
pub event_id: Option<String>, // app-side snowflake per observability.md Principle 3
pub status: Option<String>, // STARTED / RUNNING / COMPLETED / FAILED
pub created_at: Option<DateTime<Utc>>, // wall-clock at emit time
}Three layered serde aliases keep pre-EE clients working without changes:
-
name→event_type(legacy field name) -
context→payload(executor producers sendcontext; server stores aspayload) - Pre-EE clients that omit
event_id/status/created_atfall back to server-side defaults (DB snowflake / name-derivation /Utc::now()).
Mirrors the Python EventEmitRequest shape after EE-4 — both servers accept the same wire format.
Tracked on noetl/ai-meta#30 — Appendix H Rust migration umbrella. Reconciliation aligns four shapes (worker WorkerEvent, Python EventEmitRequest, Rust EventRequest, executor ExecutorEvent) so all accept the same wire format and worker switching is a one-liner.
| PR | Repo | Status |
|---|---|---|
| EE-1 | noetl/cli | ✅ merged (#37) — executor 0.3.1 enriches ExecutorEvent with optional event_id / worker_id / meta + payload serde alias |
| EE-2 | noetl/server | ✅ merged (#6) — this server's EventRequest rename + new optional fields (noetl-server 2.0.0; pipeline-fix #7 published 2.0.1) |
| EE-4 | noetl/noetl (Python) | ✅ merged (#639) — Python EventEmitRequest aliases + worker_id top-level field + EventType: Literal[...] → str (the Literal was already out of sync with the dot-notation event types used throughout production Python code) |
| EE-3 | noetl/worker | ⏳ last — replace WorkerEvent with ExecutorEvent re-export; sends new wire shape |
Both servers (Rust + Python) accept the new wire format and the legacy shape via aliases. Worker switch (EE-3) is therefore safe to land any time — partial rollouts don't break event ingestion in either direction.
| Source |
event_type field |
step / node_name field |
context / payload field |
worker_id field |
event_id field |
|---|---|---|---|---|---|
| noetl-executor 0.3.1 | event_type |
step |
context (alias: payload) |
optional worker_id
|
optional i64
|
| noetl-server (Rust) v2.0.1+ |
event_type (alias: name) |
step |
payload (alias: context) |
optional worker_id
|
optional String
|
Python EventEmitRequest (v3.0.0+) |
event_type (alias: name) |
node_name (alias: step) |
context (alias: payload) |
optional worker_id
|
optional String
|
| noetl-worker 2.1.0 (pre-EE-3) | event_type |
node_name |
payload |
(in meta) |
(server-generated) |
All four shapes accept the same wire format. The worker today still sends its current shape; both servers handle it.
-
step+statusare first-class fields rather than buried inpayload— easier for the projector + dashboard queries. -
created_atis stamped at emit time → avoids server-clock skew when ordering events. -
execution_id: i64matches the Postgresbigintcolumn type directly — no String⇄i64 conversion in the ingest path (the wire still usesStringto avoid JSON-number precision loss for large snowflakes in browser clients). - Documented in executor-crate-architecture as the design target.
Production Python code uses dot-notation event types (step.exit, call.done, command.completed, command.issued, etc.) extensively in noetl/core/dsl/engine/executor/ and noetl/server/api/core/execution.py. But the schema's EventType = Literal["step_completed", "step_started", ...] (underscored, past-tense) only accepted the underscored variants. The strict Literal was either dead code or its validation never actually fired against real worker traffic.
EE-4 loosened EventType to str; semantic validation now lives at the call site (orchestrator + projector) where the real taxonomy is enforced. The dot-notation values are the actual production taxonomy; the Literal was aspirational and never matched reality.
- Event envelope
- Event-sourced execution
- API surface
- Runtime shape (compiled + plug-in ring)
- Cursor / claim loop mode
- noetl/cli wiki
- noetl/worker wiki
- noetl/tools wiki
- noetl/noetl wiki — Python implementation (twin during migration)
- noetl/ops wiki