Eventvisor

Concepts

Event pipeline

Eventvisor is a governance pipeline. Core decides whether an event is valid, transforms it, samples it, and selects destinations. Transport modules own network delivery and reliability.

Processing order

For each track() call, Eventvisor follows this order:

  1. Find the event definition and check required attributes.
  2. Validate the original payload and apply its validation failure policy.
  3. Evaluate event conditions and sampling.
  4. Apply event transforms.
  5. Dispatch event_tracked effects and await their steps.
  6. Evaluate each destination's conditions and sampling, then apply destination transforms.
  7. Dispatch all selected destinations in parallel and wait for every attempt to settle.
  8. Emit the SDK event_tracked event.

The resolved value is the transformed event, or null when governance rejects it. track() does not promise durable delivery. A transport can send immediately, queue, batch, retry, or persist events according to its own contract.

Ordering and readiness

track() waits for SDK readiness, including persisted attributes and effects. Attribute operations are asynchronous, but public SDK operations are processed in call order. Calling setAttribute() and then track() without awaiting the first promise still guarantees that the new attribute is available to that event. Await each promise when the application needs the result or needs to handle a failure.

Destination fan-out is parallel. Do not rely on one destination completing before another. Use await eventvisor.flush() when a queueing transport must attempt all buffered work, such as before a controlled shutdown.

Effects and re-entrancy

Effect handlers should call api.track() when they need to emit another Eventvisor event. The SDK carries the active effect chain through that API and blocks a cycle before it can recurse indefinitely. The blocked dispatch is reported with the effect_reentrancy_blocked diagnostic.

Delivery contract

Core provides ordered governance and at most once dispatch to each selected transport. It does not provide durable network delivery. Immediate transports attempt delivery before track() resolves. Queueing transports accept a snapshot of the event and define their own batching, retry, overflow, and flush behaviour.

Removing a module flushes that module before closing it. Closing an instance waits for initialization, flushes every module, closes module resources, and clears SDK listeners and diagnostic subscriptions.

Previous
Persistence