feat(events): add dunite-events leaf crate (event bus + SSE adapter) #40

Merged
nrupard merged 1 commit from feat/DEV-528-events-crate into main 2026-08-06 17:46:08 +02:00
Owner

What

Adds the dunite-events leaf crate (DEV-528, under BUNYIP-340) - the in-process event bus + SSE framing extracted from bunyip, generic over the consumer's event type.

  • bus: the SseEvent trait (name() + target_user()) and EventBus<E: SseEvent> - per-user + global tokio broadcast channels with lazy per-user channel reaping. Framework-neutral (tokio only).
  • sse: the actix adapter. sse_response(bus, user_id) opens the merged (per-user + global) text/event-stream with a 25s keepalive and a resync frame on a Lagged receiver; encode_event / encode_resync do the framing.

The concrete event enum stays in the consumer (bunyip's BunyipEvent) and implements SseEvent. menkent hand-ported the same bus + /v1/events stream (MKT-16); this is the convergence target.

Deps

Adds tokio-stream (features sync, for BroadcastStream) to the workspace. actix-web / tokio / futures-util / serde / serde_json / uuid were already present. Leaf crate (no dunite-core dep).

Validation

cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings, cargo test -p dunite-events green in the pinned rust-builder image. Tests: per-user / global routing, cross-user isolation, no-subscriber noop (bus); event / resync frame shape (sse).

Consumer follow-up (bunyip, after merge)

  • event_bus.rs: keep BunyipEvent + add its impl SseEvent; re-export EventBus from the crate. web::Data<Arc<EventBus>> becomes EventBus<BunyipEvent>.
  • handlers/events.rs: the handler becomes a thin dunite_events::sse::sse_response(&bus, user_id).

Leaf crate, so bunyip's dunite-core rev does not move.

#DEV-528

## What Adds the `dunite-events` leaf crate (DEV-528, under BUNYIP-340) - the in-process event bus + SSE framing extracted from bunyip, generic over the consumer's event type. - **`bus`**: the `SseEvent` trait (`name()` + `target_user()`) and `EventBus<E: SseEvent>` - per-user + global tokio broadcast channels with lazy per-user channel reaping. Framework-neutral (tokio only). - **`sse`**: the actix adapter. `sse_response(bus, user_id)` opens the merged (per-user + global) `text/event-stream` with a 25s keepalive and a `resync` frame on a `Lagged` receiver; `encode_event` / `encode_resync` do the framing. The concrete event enum stays in the consumer (bunyip's `BunyipEvent`) and implements `SseEvent`. menkent hand-ported the same bus + `/v1/events` stream (MKT-16); this is the convergence target. ## Deps Adds `tokio-stream` (features `sync`, for `BroadcastStream`) to the workspace. `actix-web` / `tokio` / `futures-util` / `serde` / `serde_json` / `uuid` were already present. Leaf crate (no dunite-core dep). ## Validation `cargo fmt --all --check`, `cargo clippy --workspace --all-targets -- -D warnings`, `cargo test -p dunite-events` green in the pinned rust-builder image. Tests: per-user / global routing, cross-user isolation, no-subscriber noop (bus); event / resync frame shape (sse). ## Consumer follow-up (bunyip, after merge) - `event_bus.rs`: keep `BunyipEvent` + add its `impl SseEvent`; re-export `EventBus` from the crate. `web::Data<Arc<EventBus>>` becomes `EventBus<BunyipEvent>`. - `handlers/events.rs`: the handler becomes a thin `dunite_events::sse::sse_response(&bus, user_id)`. Leaf crate, so bunyip's `dunite-core` rev does not move. #DEV-528
feat(events): add dunite-events leaf crate (event bus + SSE adapter)
All checks were successful
Check / fmt + clippy + test (pull_request) Successful in 28s
create-release / create-release (pull_request) Has been skipped
72ad89a2bd
Extracts bunyip's in-process event bus + SSE framing into a leaf crate (DEV-528), generic over the consumer's event type.

bus: the SseEvent trait (name + target_user) and EventBus<E> - per-user + global tokio broadcast channels with lazy per-user channel reaping. Framework-neutral.

sse: the actix adapter. sse_response(bus, user_id) opens the merged (per-user + global) text/event-stream with a 25s keepalive and a resync frame on a Lagged receiver; encode_event/encode_resync do the framing.

The concrete event enum stays in the consumer and implements SseEvent. Adds tokio-stream (features "sync") to the workspace; actix-web/tokio/futures-util/serde/uuid already present. CLAUDE.md crates block and dependency-direction note updated.

#DEV-528
nrupard deleted branch feat/DEV-528-events-crate 2026-08-06 17:46:08 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/dunite!40
No description provided.