room

package
v0.2.17 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 27, 2026 License: MPL-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package room is an in-process pub/sub for room timelines: the room inlet publishes messages to a (tenant, room); SSE subscribers receive them live, plus a short backfill of recent ones.

Single-node by design — fleet fan-out across chassis nodes is an overlay seam (the NATS feed/trace-subscriber backends), deferred. Durable history is the event/trace log (events-as-history); the ring buffer here is only a live-backfill cache, not the system of record.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RegisterRelay added in v0.2.10

func RegisterRelay(name string, c RelayConstructor)

RegisterRelay adds a named cross-node relay backend. Called from init() in the backend package; activated by blank import. No backend is built in open core — the in-process Hub is the default and only built-in.

Types

type Deliver added in v0.2.10

type Deliver func(tenant, room string, ev Event)

Deliver injects an Event received from ANOTHER node into the local Hub. A Relay backend MUST filter out its own published Events (origin tagging) so Deliver is only ever called for remote Events — otherwise a node would double-deliver (locally and via the round-trip) and could loop.

type Event

type Event struct {
	Seq       int64  `json:"seq"`
	Room      string `json:"room"`
	Actor     string `json:"actor"`
	Text      string `json:"text"`
	MessageID string `json:"message_id,omitempty"`
}

Event is one message in a room's timeline, as published to subscribers.

type Hub

type Hub struct {
	// contains filtered or unexported fields
}

Hub fans out room Events to live subscribers and keeps a small per-room ring buffer of recent Events for subscriber backfill. Safe for concurrent use.

With a Relay attached (SetRelay), locally-published Events also fan out to other fleet nodes, and Events from other nodes arrive via Deliver. Without one, the Hub is purely in-process (single node).

func NewHub

func NewHub(ringSize int) *Hub

NewHub returns a Hub keeping the last ringSize Events per room for backfill (ringSize <= 0 defaults to 50).

func (*Hub) Deliver added in v0.2.10

func (h *Hub) Deliver(tenant, room string, ev Event)

Deliver injects an Event received from ANOTHER fleet node into this Hub's local subscribers + ring. It is the callback handed to a Relay. To bound memory it only delivers to rooms this node already has state for (something subscribed or published here) — a node with no local interest in a room drops remote Events for it rather than materializing unbounded per-room state. It re-sequences locally and does NOT relay (no loop).

func (*Hub) Publish

func (h *Hub) Publish(tenant, room, actor, text, messageID string) Event

Publish records a locally-created Event for (tenant, room) — assigning a per-room sequence, ringing it, and fanning it out to local subscribers — then relays it to other fleet nodes when a Relay is attached. Returns the stored Event.

func (*Hub) SetRelay added in v0.2.10

func (h *Hub) SetRelay(r Relay)

SetRelay attaches a cross-node relay so locally-published Events fan out to other fleet nodes. Call once at boot, before serving; nil keeps the Hub purely in-process.

func (*Hub) Subscribe

func (h *Hub) Subscribe(tenant, room string) (<-chan Event, []Event, func())

Subscribe registers a live subscriber for (tenant, room). It returns the live Event channel, a snapshot of the recent ring buffer (oldest first), and an unsubscribe func the caller MUST invoke when done (it removes the subscriber and closes the channel; calling it more than once is safe).

type Relay added in v0.2.10

type Relay interface {
	// Publish best-effort sends a locally-created Event to other nodes for
	// (tenant, room). Non-blocking by contract — it must drop rather than stall
	// the request path.
	Publish(tenant, room string, ev Event)
	// Close releases backend resources (connections, goroutines).
	Close() error
}

Relay fans room Events across fleet nodes. A node publishes its locally- created Events via Publish; Events created on OTHER nodes arrive through the Deliver callback the constructor was given (the Hub injects them into its local subscribers + ring). Single-node chassis register no relay and the Hub stays purely in-process.

The seam mirrors the trace Sink/Armable registries: open core defines the interface + registry and ships no backend; an overlay (NATS) self-registers via init() + a blank import.

func OpenRelay added in v0.2.10

func OpenRelay(name string, cfg RelayConfig, deliver Deliver) (Relay, error)

OpenRelay constructs the named relay backend, wiring deliver to its inbound feed. Unknown name is a hard error listing what is available.

type RelayConfig added in v0.2.10

type RelayConfig struct{}

RelayConfig carries backend-selecting options resolved from chassis config. Empty today; a backend reads its own connection details from its own env (the same seam discipline as trace.StoreConfig / artifact.StoreConfig).

type RelayConstructor added in v0.2.10

type RelayConstructor func(cfg RelayConfig, deliver Deliver) (Relay, error)

RelayConstructor builds a Relay, wiring deliver to its inbound subscription.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL