Skip to content

SMOODEV-1891: Connection backplane — pluggable scale-out + event-delivery seam#7

Merged
brentrager merged 2 commits into
mainfrom
SMOODEV-1891-backplane
Jun 13, 2026
Merged

SMOODEV-1891: Connection backplane — pluggable scale-out + event-delivery seam#7
brentrager merged 2 commits into
mainfrom
SMOODEV-1891-backplane

Conversation

@brentrager

Copy link
Copy Markdown
Contributor

What

The foundational build for ADR-027 — running smooth-operator as a horizontally-scaled WS service — and the plug point for non-AI realtime.

The reference server was single-process: each connection's sink is an in-process channel with no registry and no way to reach a connection from outside its own read loop. That blocks (a) >1 replica and (b) any non-agent service pushing events to a client. The Backplane is the seam for both.

  • smooth_operator::backplane (public mechanism): a Backplane async trait — attach/detach a connection's local sink, associate it with targets, publish(Target, event) to every connection for a target — plus a default InMemoryBackplane (in-memory registry + direct local delivery). Target = Connection / Session / User / Org / Agent. Runtime-agnostic: the sink is a LocalSink closure, so the lib takes no async-runtime dependency.
  • Server wiring: each connection attaches its sink on connect, associates its session + agent at create_conversation_session, and detaches on disconnect. AppState::with_backplane() (default InMemoryBackplane).
  • A Redis/NATS impl (SMOODEV-1892) makes the same publish() fan out across pods — multi-replica scale-out.

Why it matters

Backplane.publish(Target::Session(...), event) is callable by any service (job status, ingestion progress, notifications) — AI becomes one publisher among many, and realtime becomes a general pub/sub→WebSocket substrate.

Verification

  • 5 lib unit tests (publish to session/connection, multi-target, detach cleanup, unknown target).
  • 2 WS end-to-end tests: an out-of-band publisher reaches a live client over the real WebSocket; detach on disconnect stops delivery. (129 + 21 + 2 + 4 green.)
  • cargo fmt --check + clippy clean; no async-runtime dep added to the lib.

Epic SMOODEV-1887 (ADR-027). Next: SMOODEV-1892 (Redis/NATS impls).

🤖 Generated with Claude Code

…very seam

Adds the foundation for running smooth-operator as a horizontally-scaled WS
service (ADR-027) and the plug point for non-AI realtime.

- smooth_operator::backplane (lib): a `Backplane` async trait (attach/detach a
  connection's local sink, associate it with targets, publish(Target, event) to
  every connection for a target) + a default `InMemoryBackplane` (registry +
  direct local delivery). Runtime-agnostic: the sink is a `LocalSink` closure, so
  the lib takes no async-runtime dependency. `Target` = Connection/Session/User/
  Org/Agent.
- Server: each connection attaches its sink on connect, associates its session +
  agent at create-session, detaches on disconnect. AppState gains the provider
  (`with_backplane`, default InMemory).
- A Redis/NATS impl (SMOODEV-1892) makes the same publish() fan out cross-pod.

Tests: 5 lib unit (publish/associate/detach/multi-target) + 2 WS e2e (an
out-of-band publisher reaches a live client over WS; detach stops delivery on
disconnect). fmt + clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jun 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d9b4e09

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@smooai/smooth-operator Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

kind-deploy-smoke has been red on every PR (incl. #6, last merged to main):
the Dockerfile builds with `cargo build --release --locked`, which requires a
committed Cargo.lock, but .gitignore excluded it. A workspace that ships a
binary must commit its lock. Un-ignore + commit the resolved graph.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@brentrager brentrager merged commit e6d9dbe into main Jun 13, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant