sessionsync

package
v1.101.0 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

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

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

func (h *Handle) Close() error

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

func (h *Handle) PublishAPIKeyReload(ctx context.Context)

PublishAPIKeyReload announces that API keys changed so peers re-sync their in-memory key set. No-op on a nil Handle.

func (*Handle) PublishCatalogReload

func (h *Handle) PublishCatalogReload(ctx context.Context, catalogID string)

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

func (h *Handle) PublishConnectionReload(ctx context.Context, kind, name, op string)

PublishConnectionReload announces that the (kind, name) connection changed so peers rebuild it. op is an opaque intent string ("upsert"/"delete") the bus carries verbatim to the peer handler. No-op on a nil Handle.

func (*Handle) PublishPersonaReload

func (h *Handle) PublishPersonaReload(ctx context.Context)

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

func (h *Handle) SessionStore() session.Store

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

func (h *Handle) StatelessForced() bool

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 receives (kind, name, op) where op is the opaque intent string
	// the publisher passed to PublishConnectionReload ("upsert"/"delete", empty
	// for a legacy pre-op event). The bus does not interpret op; the handler
	// does.
	Connection func(kind, name, op 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.

Jump to

Keyboard shortcuts

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