Archived. Eventra is no longer maintained. The canonical reusable runtime event bus, including the OpenTelemetry export and SQLite outbox migration from Eventra #65, now lives in phenoEvents, merged in phenoEvents #30. Do not start new work here.
Eventra is a Rust workspace for event-driven systems with CQRS/event-sourcing building blocks, a framework-local in-memory event bus, and transactional outbox support.
eventkitinsrc/is the top-level framework crate.eventkit-obsinrust/eventkit-obs/provides structured logging, health probes, and theeventkit-healthcheckCLI.phenotype-event-contractsdefines event and event-bus traits.phenotype-event-busprovides the generic event envelope, in-memory bus, outbox traits, relay, metrics, and SQLite/Postgres adapters behind features.phenotype-event-sourcingandphenotype-error-coreprovide supporting framework types.
Prerequisites:
- Rust 1.75+ from
rust-toolchain.toml
Clone and build the workspace:
git clone https://github.com/KooshaPari/Eventra.git
cd Eventra
cargo build --workspaceTo use the crates from another project, add the crate you need to your Cargo.toml and depend on the workspace package directly, for example:
[dependencies]
eventkit = { git = "https://github.com/KooshaPari/Eventra", package = "eventkit" }
phenotype-event-bus = { git = "https://github.com/KooshaPari/Eventra", package = "phenotype-event-bus" }The repository is library-first. The only shipped binary is the healthcheck CLI in eventkit-obs.
cargo run -p eventkit-obs --bin eventkit-healthcheckFor HTTP probe mode, point the CLI at a health endpoint exposed by your service:
cargo run -p eventkit-obs --bin eventkit-healthcheck -- http://127.0.0.1:8080/healthDocker and Compose are available for the local healthcheck container:
docker build -t eventra/eventkit:latest .
docker compose up --buildeventkit exposes the framework modules and an idempotent tracing initializer:
eventkit::init_tracing();The default tracing filter honors RUST_LOG and falls back to info,eventkit=debug.
src/application/event_bus.rs implements a synchronous in-process bus over the framework Event and EventHandler traits.
publishroutes byevent.metadata.event_type.subscriberegisters one handler per event type returned byhandler.event_types().- A failing handler is logged and does not abort delivery to the remaining handlers.
phenotype-event-bus defines:
EventIdas a ULID-backed identifier.EventEnvelope<T>withsource,timestamp,payload,correlation_id, andcausation_id.EventBusas an async publish/subscribe/request/close trait.memory::InMemoryEventBusfor tests and simple local use.
Example:
use phenotype_event_bus::EventEnvelope;
let envelope = EventEnvelope::new("orders.created", serde_json::json!({"id": 1}))
.with_correlation_id("cor-123")
.with_causation_id("cause-456");phenotype-event-bus also provides the transactional outbox pattern:
OutboxEntrystores the envelope, aggregate id, timestamps, attempt count, and last error.OutboxStoreis the storage trait.InMemoryOutboxis for tests and single-process development.PostgresOutboxis enabled by thepostgresfeature and usesSELECT ... FOR UPDATE SKIP LOCKEDto support multiple relay workers.SqliteOutboxis enabled by thesqlitefeature and is intended for embedded/dev/test use.OutboxRelaydrains unpublished rows, invokes a user-supplied publisher, records failures, and backs off between retries.
The key rule is dual-write safety: write the domain mutation and the outbox row in the same database transaction, then let the relay publish later. Consumers must treat OutboxEntry::id as the deduplication key.
Framework crate (eventkit)
├─ domain
│ ├─ Event, Aggregate, EventHandler traits
│ └─ EventBus port
├─ application
│ └─ in-memory EventBus adapter
└─ infrastructure
└─ supporting adapters and integration helpers
Runtime/event-bus support crate (phenotype-event-bus)
├─ EventId + EventEnvelope<T>
├─ EventBus trait and in-memory bus
├─ OutboxEntry + OutboxStore
├─ OutboxRelay + retry/backoff loop
├─ Outbox metrics and tracing spans
├─ SQLite outbox adapter
└─ Postgres outbox adapter
See .env.example for the current environment variables.
Important values:
RUST_LOGEVENTKIT_LOG_FORMATEVENTKIT_HEALTH_PORTEVENTKIT_HEALTHCHECK_TIMEOUT_MSOUTBOX_POLL_INTERVAL_MSOUTBOX_BATCH_SIZEOUTBOX_SHUTDOWN_TIMEOUT_SECS
docs/deploy.mdfor deployment and health-check guidancedocs/disposition/phenotype-event-bus-runtime-boundary.mdfor the runtime boundary decisionSPEC.mdfor the higher-level framework specification
MIT OR Apache-2.0