Documentation
¶
Overview ¶
Package sessionsync assembles the session / cross-replica-sync layer behind one Handle: the externalized session store (memory or postgres), the per-session enrichment-dedup cache, the client-facing MCP notification broadcaster, and the dedicated cross-replica reload bus (its own broadcaster channel plus the publish/subscribe machinery).
Construction takes explicit inputs — a *sql.DB, the resolved session / broadcast config values, an optional injected session store, and the reload handlers Platform re-materializes local state through — so the subsystem is constructible and testable without a Platform. It imports pkg/session, pkg/session/postgres, and pkg/middleware, never pkg/platform. The *sql.DB and the config values back many other subsystems, so they stay owned by Platform and are passed in rather than owned here.
Construction is two-phase: New builds the store + both broadcasters + reload bus (owning their cleanup and subscriber goroutines), and StartCache builds the enrichment-dedup cache during middleware assembly (gated by config on the Platform side). The reload re-materialization handlers stay on Platform (they reach into the connection store, toolkit registry, persona registry, and API-key store — state this package does not own) and are injected as callbacks. Close is the shutdown seam Platform wires into its own lifecycle.
Index ¶
- type Config
- type Handle
- func (h *Handle) Broadcaster() session.Broadcaster
- func (h *Handle) Close() error
- func (h *Handle) PublishAPIKeyReload(ctx context.Context)
- func (h *Handle) PublishCatalogReload(ctx context.Context, catalogID string)
- func (h *Handle) PublishConnectionReload(ctx context.Context, kind, name string)
- func (h *Handle) PublishPersonaReload(ctx context.Context)
- func (h *Handle) SessionCache() *middleware.SessionEnrichmentCache
- func (h *Handle) SessionStore() session.Store
- func (h *Handle) StartCache(entryTTL, sessionTimeout time.Duration) *middleware.SessionEnrichmentCache
- func (h *Handle) StatelessForced() bool
- type ReloadHandlers
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Store selects the session store backend: "database", "memory", or ""
// (memory). Ignored when an injected store is supplied to New.
Store string
// TTL is the resolved session lifetime; CleanupInterval is how often the
// store's cleanup routine runs. Both are already defaulted by the caller.
TTL time.Duration
CleanupInterval time.Duration
// DSN is the database connection string; empty disables the postgres
// broadcasters (memory fan-out only). BroadcastChannel overrides the
// postgres LISTEN/NOTIFY channel; empty uses the package default.
DSN string
BroadcastChannel string
}
Config carries the resolved session / broadcast values the owner needs to assemble the layer. Platform resolves defaults (TTL, cleanup interval) before passing them so this package stays free of the platform's defaulting rules.
type Handle ¶
type Handle struct {
// contains filtered or unexported fields
}
Handle owns the assembled session / cross-replica-sync layer: the session store (and its cleanup goroutine), the enrichment-dedup cache (and its cleanup goroutine, started by StartCache), the client-facing broadcaster, and the dedicated reload broadcaster + bus (and the subscriber goroutine). The read accessors expose the store / broadcaster / cache that Platform surfaces through its SessionStore() / Broadcaster() accessors, the HTTP session resolver, session-handle minting, and the admin session export/restore; the Publish*Reload delegators back the Platform wrappers admin handlers call. Close is the shutdown seam Platform wires into its own lifecycle.
func New ¶
func New(db *sql.DB, cfg Config, injectedStore session.Store, handlers ReloadHandlers) (*Handle, error)
New assembles the session store, both broadcasters, and the reload bus from an explicit *sql.DB, the resolved config, an optional injected store, and the reload handlers. When injectedStore is non-nil it is used verbatim (the admin SessionStore override path) — store selection, the cleanup routine, and stateless forcing are all skipped, but the broadcasters and reload bus are still wired so Broadcaster() is non-nil and cross-replica reload still works.
It returns an error when Config.Store is "database" but db is nil, or when Config.Store is an unknown value; otherwise the returned Handle is non-nil and its Broadcaster is guaranteed non-nil (memory fallback).
func (*Handle) Broadcaster ¶
func (h *Handle) Broadcaster() session.Broadcaster
Broadcaster returns the client-facing MCP notification broadcaster. Non-nil after a successful New (memory fallback guarantees it); nil only on a nil Handle.
func (*Handle) Close ¶
Close tears down the layer in order: stop the enrichment cache, close the session store, close the client broadcaster, then cancel the reload subscriber and close the reload broadcaster. The broadcasters must close before Platform closes its *sql.DB because the postgres broadcasters hold their own dedicated LISTEN connections. Returns the joined store + client-broadcaster close errors; the reload-broadcaster close error is best-effort (the reload channel is a control-plane convenience, not a data path). No-op on a nil Handle.
func (*Handle) PublishAPIKeyReload ¶
PublishAPIKeyReload announces that API keys changed so peers re-sync their in-memory key set. No-op on a nil Handle.
func (*Handle) PublishCatalogReload ¶
PublishCatalogReload announces that an API catalog's specs changed so peers rebuild every connection referencing it. No-op on a nil Handle.
func (*Handle) PublishConnectionReload ¶
PublishConnectionReload announces that the (kind, name) connection's stored config changed so peers rebuild it. No-op on a nil Handle.
func (*Handle) PublishPersonaReload ¶
PublishPersonaReload announces that persona definitions changed so peers reconcile their persona registry. No-op on a nil Handle.
func (*Handle) SessionCache ¶
func (h *Handle) SessionCache() *middleware.SessionEnrichmentCache
SessionCache returns the enrichment-dedup cache, or nil on a nil Handle or when StartCache was never called (session_dedup disabled).
func (*Handle) SessionStore ¶
SessionStore returns the externalized session store, or nil on a nil Handle.
func (*Handle) StartCache ¶
func (h *Handle) StartCache(entryTTL, sessionTimeout time.Duration) *middleware.SessionEnrichmentCache
StartCache builds the per-session enrichment-dedup cache and starts its cleanup goroutine. Callers gate this on config (session_dedup enabled); when not called the cache stays nil and SessionCache returns nil — the disabled no-op. No-op on a nil Handle or a repeat call, so a second call cannot leak the first cache's goroutine. Returns the cache for the caller to wire into the enrichment middleware config.
func (*Handle) StatelessForced ¶
StatelessForced reports whether the database store was selected and the SDK's built-in session map must therefore be bypassed. Platform applies this to its Server.Streamable config after New.
type ReloadHandlers ¶
type ReloadHandlers struct {
Connection func(kind, name string)
Catalog func(catalogID string)
Persona func()
APIKey func()
}
ReloadHandlers carries the local re-materialization callbacks the reload subscriber invokes when a peer replica announces a configuration change. They stay on Platform (they reach into Platform-owned state) and are injected here so the bus is unit-testable in isolation. Any nil handler means "this subsystem does not participate in cross-replica reload"; the event is ignored. This is also the reloadBus's handler type, so New passes it straight through.