Documentation
¶
Overview ¶
Snapshot assembly. build is intentionally a thin orchestrator: it computes the input-id sets and calls each kind's addX method in the order their dependencies require. The per-kind logic (sanitize + register) lives in build_<kind>.go.
Cross-references in each entity are *sanitized* against the input enabled-id sets before insertion: a ref to a missing or disabled row is silently dropped from the snapshot copy. The full row stays in Postgres for the control plane. Reload never fails over a stale ref — the snapshot is always the consistent reachable subgraph.
Helpers shared by the per-kind build_*.go files.
The build pipeline is intentionally one file per resource: each build_<kind>.go owns its sanitizer (cross-ref filtering) and its "register into the Snapshot" step. build.go orchestrates the order; it never reads or writes Snapshot maps directly.
notify.go implements the PG NOTIFY listener and debouncer for catalog events.
The listener acquires a dedicated connection from the pool, issues LISTEN catalog_events, and forwards parsed events to the debouncer. A flush goroutine drains the debouncer every second, fetches each affected row via the narrow store interfaces, and applies it to the Catalog via the appropriate Apply* method.
On any connection error the listener logs, waits 1 s, and reconnects — it never panics. Run blocks until ctx is cancelled.
policy_allow.go precomputes, per policy, the concrete set of (model, host) combinations the policy grants — so request-time authorization is an O(1) membership test instead of a per-request ref-matching loop.
Only EXPLICIT-grant policies (ModelIDs and/or Models set) get a set. An implicit-wildcard policy (both empty) grants everything reachable via its hostkeys; materializing that would be the whole catalog, so it gets no set and PolicyAllowsCombo returns true — the hostkey-coverage gate at resolution is the real authorization in that case. The same sets gate the host tier policy a hostkey is attached to (see routing's key selection).
Built off the hot path: once in Build, and recomputed on any reconcile that can change a grant (provider/host/model/policy writes). It reads policies + models + hosts + providers, so it must run after those are indexed.
Package catalog is the composition layer: it pulls the entity stores together into an atomic in-memory Snapshot the request path can read in O(1). Snapshots are immutable; Reload rebuilds and atomically swaps.
Membership rule (single, simple): every enabled row of every kind enters the snapshot. There is no reachability filter — a Model not bound to any Policy still appears (it's just unreachable through PoolModels until someone wires it up). The "enabled" flag is the entire toggle mechanism.
Reverse joins (modelsByPolicy, pricingByModelHost, etc.) are derived indices over the snapshot — they hold pointers to the same rows.
Index ¶
- func Bootstrap(ctx context.Context, opts BootstrapOptions) (*Catalog, *Listener, *Stores, error)
- func BootstrapStores(ctx context.Context, opts BootstrapOptions) (*Catalog, *Stores, error)
- type BindingLister
- type BootstrapOptions
- type Catalog
- func (c *Catalog) ApplyHostDelete(id string) error
- func (c *Catalog) ApplyHostKeyDelete(id string) error
- func (c *Catalog) ApplyHostKeyUpsert(k *hostkey.HostKey) error
- func (c *Catalog) ApplyHostUpsert(h *host.Host) error
- func (c *Catalog) ApplyModelDelete(id string) error
- func (c *Catalog) ApplyModelUpsert(m *model.Model) error
- func (c *Catalog) ApplyPolicyDelete(id string) error
- func (c *Catalog) ApplyPolicyUpsert(p *policy.Policy) error
- func (c *Catalog) ApplyPricingDelete(id string) error
- func (c *Catalog) ApplyPricingUpsert(p *pricing.Pricing) error
- func (c *Catalog) ApplyProviderDelete(id string) error
- func (c *Catalog) ApplyProviderUpsert(p *provider.Provider) error
- func (c *Catalog) ApplyRateLimitDelete(id string) error
- func (c *Catalog) ApplyRateLimitUpsert(r *ratelimit.RateLimit) error
- func (c *Catalog) ApplyRelayKeyDelete(id string) error
- func (c *Catalog) ApplyRelayKeyUpsert(k *relaykey.RelayKey) error
- func (c *Catalog) Current() *Snapshot
- func (c *Catalog) Hydrate(ctx context.Context, stores *Stores, opts BootstrapOptions) (*Listener, error)
- func (c *Catalog) IsReady() bool
- func (c *Catalog) OnSettingsChange(section string, fn func())
- func (c *Catalog) Reload(ctx context.Context) error
- func (c *Catalog) Setting(section string) (any, bool)
- type HostKeyLister
- type HostLister
- type Listener
- type ModelLister
- type PolicyLister
- type PricingLister
- type ProviderLister
- type RateLimitLister
- type RelayKeyLister
- type SettingsLister
- type Snapshot
- func (s *Snapshot) AllBindings() []*binding.Binding
- func (s *Snapshot) AllHostKeys() []*hostkey.HostKey
- func (s *Snapshot) AllModels() []*model.Model
- func (s *Snapshot) AllPolicies() []*policy.Policy
- func (s *Snapshot) AllPricings() []*pricing.Pricing
- func (s *Snapshot) AllProviders() []*provider.Provider
- func (s *Snapshot) AllRateLimits() []*ratelimit.RateLimit
- func (s *Snapshot) AllRelayKeys() []*relaykey.RelayKey
- func (s *Snapshot) Binding(id string) (*binding.Binding, bool)
- func (s *Snapshot) BindingForModelHost(modelID, hostID string) (*binding.Binding, bool)
- func (s *Snapshot) BindingsForModel(modelID string) []*binding.Binding
- func (s *Snapshot) Dependents(kind refKind, id string) []refKey
- func (s *Snapshot) EnabledHosts() []*host.Host
- func (s *Snapshot) EnabledModels() []*model.Model
- func (s *Snapshot) Host(id string) (*host.Host, bool)
- func (s *Snapshot) HostByName(name string) (*host.Host, bool)
- func (s *Snapshot) HostKey(id string) (*hostkey.HostKey, bool)
- func (s *Snapshot) HostKeysForHost(hostID string) []*hostkey.HostKey
- func (s *Snapshot) HostKeysInPolicy(policyID string) []*hostkey.HostKey
- func (s *Snapshot) HostSlug(hostID string) (string, bool)
- func (s *Snapshot) Hosts() []*host.Host
- func (s *Snapshot) Model(id string) (*model.Model, bool)
- func (s *Snapshot) ModelsByName(name string) []*model.Model
- func (s *Snapshot) ModelsByProvider(providerID string) []*model.Model
- func (s *Snapshot) ModelsInPolicy(policyID string) []*model.Model
- func (s *Snapshot) Policy(id string) (*policy.Policy, bool)
- func (s *Snapshot) PolicyAllowsCombo(policyID, modelID, hostID string) bool
- func (s *Snapshot) PolicyByName(name string) (*policy.Policy, bool)
- func (s *Snapshot) PriceByModelHost(modelID, hostID string) (*pricing.Pricing, bool)
- func (s *Snapshot) Pricing(id string) (*pricing.Pricing, bool)
- func (s *Snapshot) Provider(id string) (*provider.Provider, bool)
- func (s *Snapshot) ProviderByName(name string) (*provider.Provider, bool)
- func (s *Snapshot) ProviderSlug(providerID string) (string, bool)
- func (s *Snapshot) RateLimit(id string) (*ratelimit.RateLimit, bool)
- func (s *Snapshot) RateLimitByName(name string) (*ratelimit.RateLimit, bool)
- func (s *Snapshot) RateLimitOfPolicy(policyID string) *ratelimit.RateLimit
- func (s *Snapshot) RelayKey(id string) (*relaykey.RelayKey, bool)
- func (s *Snapshot) RelayKeyByHash(hash string) (*relaykey.RelayKey, bool)
- func (s *Snapshot) ResolveSnapshot(key string) (*model.Model, *model.Snapshot, string, bool)
- func (s *Snapshot) SnapshotByName(name string) (*model.Model, *model.Snapshot, bool)
- type Stores
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Bootstrap ¶
Bootstrap is the legacy one-shot: stores + Hydrate in a single call. Kept for tests and any caller that doesn't need split-boot semantics. Returns the same triple as before plus the listener primed for Run.
func BootstrapStores ¶
BootstrapStores wires the eight entity stores against the pool and constructs a Catalog. Does NOT touch row data — no seed, no Reload. Use when the control plane needs the stores but data-plane readiness is deferred (see (*Catalog).Hydrate). Cheap and rarely fails.
Types ¶
type BindingLister ¶
type BootstrapOptions ¶
type BootstrapOptions struct {
Pool *pgxpool.Pool
MasterKey []byte
// AutoSeedDir, when non-empty AND the catalog is empty in PG, triggers
// a YAML import from this directory before the initial Reload. The
// expected layout matches wyolet/relay-catalog's data/ tree (providers/
// <provider>/{provider.yaml,models/}, hosts/<host>/{host.yaml,pricing/,
// policies/}). filepath.WalkDir walks the tree; dispatch is by the
// kind field in each YAML doc, so the nested layout is transparent.
// Idempotent: if any catalog row already exists, seeding is skipped.
AutoSeedDir string
}
BootstrapOptions configures the one-call Bootstrap helper. Pool and MasterKey are required; MasterKey may be nil if stored-mode HostKeys aren't in use.
type Catalog ¶
type Catalog struct {
// contains filtered or unexported fields
}
Catalog is the long-lived composition object. Holds the entity stores and the current Snapshot pointer. Construct one per process; call Reload at boot and whenever PG state changes (admin write, NOTIFY watcher).
func New ¶
func New( providers ProviderLister, hosts HostLister, policies PolicyLister, models ModelLister, keys HostKeyLister, rateLimits RateLimitLister, relayKeys RelayKeyLister, pricings PricingLister, bindings BindingLister, ) *Catalog
New constructs a Catalog backed by the supplied stores. Initial Snapshot is empty; call Reload before serving traffic.
func (*Catalog) ApplyHostDelete ¶
func (*Catalog) ApplyHostKeyDelete ¶
func (*Catalog) ApplyModelDelete ¶
func (*Catalog) ApplyPolicyDelete ¶
func (*Catalog) ApplyPricingDelete ¶
func (*Catalog) ApplyProviderDelete ¶
func (*Catalog) ApplyProviderUpsert ¶
func (*Catalog) ApplyRateLimitDelete ¶
func (*Catalog) ApplyRateLimitUpsert ¶
func (*Catalog) ApplyRelayKeyDelete ¶
func (*Catalog) ApplyRelayKeyUpsert ¶
func (*Catalog) Current ¶
Current returns the live Snapshot. Safe to call from any goroutine; the returned pointer is immutable until the next successful Reload.
func (*Catalog) Hydrate ¶
func (c *Catalog) Hydrate(ctx context.Context, stores *Stores, opts BootstrapOptions) (*Listener, error)
Hydrate is the expensive half of bootstrap: reload settings, load the hostkey master-key version, optionally auto-seed from YAML, run the first catalog Reload, and construct a NOTIFY listener primed for Run. On any error the Catalog's IsReady stays false and the caller can retry — handlers gate on it and return 503 in the meantime.
func (*Catalog) IsReady ¶
IsReady reports whether the catalog has built its first snapshot successfully. Until then, the in-memory snapshot is the zero-value returned by New — empty maps that look identical to a legitimately empty catalog. The inference plane uses this to refuse traffic with 503 instead of silently serving "no models found" lookups.
func (*Catalog) OnSettingsChange ¶
OnSettingsChange registers fn to run whenever section's value changes (upsert or delete), after the new value is visible to Setting. fn runs synchronously on the NOTIFY listener goroutine, which applies catalog events serially — so fn MUST be cheap and non-blocking. A consumer with heavy work (sink rebuild, network I/O) should have fn do a non-blocking signal and perform the work on its own goroutine. Subscriptions are process-lifetime; there is no unsubscribe.
type HostKeyLister ¶
type Listener ¶
type Listener struct {
// contains filtered or unexported fields
}
Listener subscribes to catalog_events NOTIFY, debounces the payload stream, and applies incremental updates to the Catalog.
func NewListener ¶
NewListener constructs a Listener. Call Run to start it.
type PolicyLister ¶
type PricingLister ¶
type ProviderLister ¶
type RateLimitLister ¶
type RelayKeyLister ¶
type SettingsLister ¶
type SettingsLister interface {
List(ctx context.Context) ([]*settings.Row, error)
Get(ctx context.Context, section string) (*settings.Row, error)
}
SettingsLister is the narrow read interface the catalog needs to bootstrap and refresh the settings cache. *settings.Store satisfies it.
type Snapshot ¶
type Snapshot struct {
// contains filtered or unexported fields
}
Snapshot is the immutable in-memory view. All maps are populated at construction and never written after — read accessors are safe to call from any goroutine.
func Build ¶
func Build( provs []*provider.Provider, hosts []*host.Host, pols []*policy.Policy, rks []*relaykey.RelayKey, models []*model.Model, keys []*hostkey.HostKey, rls []*ratelimit.RateLimit, pricings []*pricing.Pricing, bindings []*binding.Binding, ) *Snapshot
Build assembles a Snapshot from entity slices using the same sanitize rules as Reload. Used by catalog-embed and tests; callers supply only the kinds they need — pass nil/empty slices for the rest.
func (*Snapshot) AllBindings ¶
AllBindings returns every binding in the snapshot, sorted by name.
func (*Snapshot) AllHostKeys ¶
AllHostKeys returns every HostKey in the snapshot, sorted by slug.
func (*Snapshot) AllModels ¶
AllModels returns every enabled Model in stable slug order. Used by the /catalog/resolve endpoint for host-only refs ("@bedrock") that need to walk the entire catalog rather than a single provider.
func (*Snapshot) AllPolicies ¶
AllPolicies returns every Policy in the snapshot, sorted by slug.
func (*Snapshot) AllPricings ¶
AllPricings returns every Pricing in the snapshot, sorted by slug.
func (*Snapshot) AllProviders ¶
AllProviders returns every Provider in the snapshot, sorted by slug.
func (*Snapshot) AllRateLimits ¶
AllRateLimits returns every RateLimit in the snapshot, sorted by slug.
func (*Snapshot) AllRelayKeys ¶
AllRelayKeys returns every RelayKey in the snapshot, sorted by slug.
func (*Snapshot) BindingForModelHost ¶
BindingForModelHost returns the binding for (modelID, hostID), or false. O(1) — the routing hot-path lookup.
func (*Snapshot) BindingsForModel ¶
BindingsForModel returns the bindings declared for a model, sorted by binding name. The returned slice must not be mutated.
func (*Snapshot) Dependents ¶
Dependents returns every refKey that depends on (kind, id). nil if none. The slice is freshly allocated; mutating it doesn't affect the snapshot.
func (*Snapshot) EnabledHosts ¶
EnabledHosts returns enabled hosts sorted by Meta.Name.
func (*Snapshot) EnabledModels ¶
EnabledModels returns enabled models sorted by Meta.Name.
func (*Snapshot) HostByName ¶
HostByName returns the enabled Host with this slug, or false.
func (*Snapshot) HostKeysForHost ¶
HostKeysForHost returns every enabled HostKey whose Spec.HostID matches hostID. Order is by hostkey slug — stable across snapshots. Used by routing's policy-less flow (settings.Inference.AllowMissingPolicy) where the policy doesn't narrow the pool.
func (*Snapshot) HostKeysInPolicy ¶
HostKeysInPolicy returns the HostKeys attached to this Policy in declaration order (relevant for KeySelectionPrioritized).
func (*Snapshot) Hosts ¶
Hosts returns all enabled Host rows. Stable order by slug. Used by the /v1/proxy/hosts list endpoint.
func (*Snapshot) ModelsByName ¶
ModelsByName returns every enabled Model whose Meta.Name matches. The slug is unique per kind, but the index is multivalued to absorb transient overlap during reload. Customer-facing addressing uses SnapshotByName instead — this accessor is admin-only.
func (*Snapshot) ModelsByProvider ¶
ModelsByProvider returns every enabled Model whose owning Provider matches providerID. Stable order by slug. Used by the /catalog/resolve admin endpoint to enumerate a provider's catalog.
func (*Snapshot) ModelsInPolicy ¶
ModelsInPolicy returns the Models attached to this Policy in declaration order. nil if the Policy is unknown or empty.
func (*Snapshot) PolicyAllowsCombo ¶
PolicyAllowsCombo reports whether the policy grants (modelID, hostID). A policy with no materialized set is an implicit wildcard (or has no explicit grants tracked here) and allows everything — implicit-wildcard customer policies handle deprecation separately at resolution; tier policies allow all by design.
func (*Snapshot) PolicyByName ¶
PolicyByName returns the enabled Policy with this slug, or false.
func (*Snapshot) PriceByModelHost ¶
PriceByModelHost returns the Pricing that covers (modelID, hostID), or false.
func (*Snapshot) ProviderByName ¶
ProviderByName returns the enabled Provider with this slug, or false.
func (*Snapshot) ProviderSlug ¶
ProviderSlug returns the Provider.Meta.Name for the given Provider id, or false. Hot-path resolution uses this to compare a Model's owning Provider against the suffix/header hint without needing the full Provider row.
func (*Snapshot) RateLimitByName ¶
RateLimitByName returns the enabled RateLimit with this slug, or false. Used by proxy-mode dispatch to look up the system-owned inference-api-proxy / inference-api-proxy-anonymous buckets.
func (*Snapshot) RateLimitOfPolicy ¶
RateLimitOfPolicy returns the single RateLimit bound to this Policy, or nil when none is configured.
func (*Snapshot) RelayKeyByHash ¶
RelayKeyByHash is the hot-path inbound-auth lookup. Returns the RelayKey whose Spec.KeyHash matches. Caller checks IsActive.
func (*Snapshot) ResolveSnapshot ¶
ResolveSnapshot maps a slug-normalized model ref to its model + snapshot, plus an optional pinned HostID (set when the ref named a host via "@host"). Bare snapshot names win over synthesized aliases. The caller normalizes the key with slug.From.
func (*Snapshot) SnapshotByName ¶
SnapshotByName returns the Model + Snapshot for a pinned snapshot name, or false. Snapshot names are catalog-wide unique (validation enforces no collision with the owning Model's name or aliases).
type Stores ¶
type Stores struct {
Provider *provider.Store
Host *host.Store
Model *model.Store
HostKey *hostkey.Store
RateLimit *ratelimit.Store
Policy *policy.Store
Pricing *pricing.Store
Binding *binding.Store
RelayKey *relaykey.Store
Settings *settings.Store
// Secrets is the shared secret-resolution registry (env + stored
// backends). Exposed so data-plane components (e.g. the payload-logging
// controller resolving S3 credentials) resolve through the same seam.
Secrets *pkgsecret.Registry
}
Stores bundles the eight entity stores constructed by Bootstrap. Exposed so callers (admin handlers, seed CLI re-runs, tests) can reach the same underlying stores without re-wiring.
Source Files
¶
- boot.go
- build.go
- build_binding.go
- build_common.go
- build_host.go
- build_hostkey.go
- build_model.go
- build_policy.go
- build_pricing.go
- build_provider.go
- build_ratelimit.go
- build_relaykey.go
- catalog.go
- clone.go
- notify.go
- policy_allow.go
- reconcile.go
- reconcile_validate.go
- refs.go
- resanitize.go
- settings.go
- snapshot.go
- snapshot_embed.go
- validate.go