Skip to main content

Module triggers

Module triggers 

Source
Expand description

Host-side dispatch for TriggerPlugin registrations (M5f).

Bridges PluginRegistry::triggers() into the transaction commit path. The dispatcher builds a per-phase routing table once per commit, drains mutation events from the transaction’s private L0 buffer into a stable Arrow RecordBatch, applies subscription selectors (event-kind mask + label / edge-type / property filter), and invokes each matching trigger at the appropriate phase.

Phase ordering inside a single commit:

  1. BeforeMutation then BeforeCommit — fired before the writer lock is taken. Synchronous reject aborts the transaction.
  2. WAL flush + L1 merge run.
  3. AfterMutation then AfterCommit — fired after publish. Async fire-mode triggers are spawned onto the tokio runtime so the writer’s hot path stays untouched.

Behavior contract:

  • predicate_source is compiled at router build (per-commit) via uni_cypher::parse_expression → AST property-ref rewrite → cypher_expr_to_df → DataFusion PhysicalExpr, and evaluated against the per-row event batch in filter_for. Predicates may reference the event-row columns (event_kind, vid_or_eid, label, property, old_value, new_value) as well as per-entity properties: n.foo reads the new (post-mutation) property value, old.foo reads the pre-image. Referenced property keys are tracked in RouteEntry::properties_referenced so MutationEvents::from_l0_with_probe materializes exactly those keys into the per-row property bags — predicate-gated cost, no work for property-free predicates.
  • TriggerOutcome::Defer enqueues the trigger fire into the per-Uni DeferralQueue (in-memory, ticked at 50ms by the background task spawned in Uni::build). Items re-fire on the next tick; re-deferring is capped at DEFER_MAX_ATTEMPTS. Restart-durable persistence lives with the M11 CDC scheduler.
  • NODE_CREATE / NODE_UPDATE / NODE_DELETE (and the edge analogs) are distinguished via a committed-state probe (PreExistingProbe) passed to MutationEvents::from_l0_with_probe. The probe covers (a) the current L0 buffer + pending-flush L0s via PreExistingProbe::from_l0_chain (sync, no I/O) and (b) the L1 storage layer via PreExistingProbe::extend_with_l1 (async, batched _vid IN (…) scan per label, chunked at 1024 VIDs). Callers that construct MutationEvents without a probe (MutationEvents::from_l0) fall back to emitting NODE_UPDATE / EDGE_UPDATE for every non-tombstoned write.
  • old_value is populated from the L0-chain probe for vertices and edges visible there, and from the L1 probe (which now projects every property column on the candidate label) for vertices that were drained out of L0 by a previous flush. Edge pre-images are captured in the L0 chain via edge_properties.

Structs§

DeferralQueue
In-memory deferral queue for TriggerOutcome::Defer.
MutationEvents
In-memory, untyped event log drained from tx_l0. Held by value across the commit boundary and filtered per-route on dispatch.
PreExistingProbe
Snapshot of the committed graph state used to (a) distinguish CREATE from UPDATE in MutationEvents::from_l0_with_probe and (b) populate old_value for vertex and edge mutation events.
TriggerRouter
Per-commit trigger dispatcher.

Functions§

event_row_schema
Canonical Arrow schema for the per-row event batch handed to each TriggerPlugin::fire call. Kept in one place so filter_for and the predicate_source compiler agree on column names + types.
tx_id_to_u64
Convenience: stable-hash a &str tx id (commit path stores tx_id as String) down to the u64 the TriggerContext carries.