router

package
v0.2.5 Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package router is the edge request matcher (ADR-0110, F79): it compiles the Ready Route set into a host/path/method table and resolves a public data-plane request to a target (namespace, function). It RESOLVES, it does not proxy — the data-plane handler then runs the existing activator hop, so scale-to-zero is preserved. It is an internal component (interface + one table impl); no external driver is anticipated (the external gateway is the gateway.Gateway port's V2 concern, not this invoke-path matcher).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Aggregator

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

Aggregator is the single sole-writer of a Router's replace-all edge table (ADR-0138): it merges per-source Entry slices into one union and programs it atomically. It implements EntrySetter. Safe for concurrent use. This is the "aggregation seam" that lets a second edge source (an exposed catalog) coexist with user Routes instead of clobbering them.

func NewAggregator

func NewAggregator(p Programmer, log *slog.Logger) *Aggregator

NewAggregator builds an Aggregator over the edge Router's replace-all Program. log nil ⇒ Default.

func (*Aggregator) Set

func (a *Aggregator) Set(ctx context.Context, source string, entries []Entry) error

Set replaces source's entries (nil/empty clears it), recomputes the union across all sources, and programs it in a single Router.Program call — all under the lock, so the router only ever sees a self-consistent full snapshot. Sources are concatenated in sorted key order (deterministic; the Router itself re-sorts rows longest-path-first, so cross-source order does not affect matching). On a Program error the source map is left updated (committed) so the next Set — from this or any other source — re-programs the full union: idempotent, self-healing recovery with no permanent route loss. The error is still returned so the caller retries its own reconcile.

type CompiledRule

type CompiledRule struct {
	Path     string          // the rule prefix, e.g. "/orders"
	Exact    bool            // pathType == Exact
	Methods  map[string]bool // nil/empty ⇒ all methods
	Function v1.ObjectName
	// Static, when non-nil, is a static Bucket-prefix backend (ADR-0120, F82); Function is then unused
	// and the data-plane serves it via internal/edge/static (no activator hop).
	Static *v1.StaticBackend
	// Upstream, when non-empty, is a NODE-PRIVATE in-daemon reverse-proxy target (ADR-0138): the
	// data-plane reverse-proxies a match here instead of resolving a Function/Static. It is set ONLY
	// by trusted in-daemon reconcilers (the CatalogService reconciler → its catalog::query PEP proxy),
	// never from a user-authored Route — a user backend has no Upstream arm, so the edge cannot be
	// pointed at an arbitrary in-daemon address (no SSRF). Function/Static are then unused.
	Upstream string
}

CompiledRule is one path rule ready to match.

type Entry

type Entry struct {
	Namespace v1.NamespaceName
	Host      string      // exact; "" matches any host
	Auth      v1.AuthMode // the Route's edge auth stance (ADR-0113); "" ⇒ inherit the namespace default
	Rules     []CompiledRule
}

Entry is one Route's compiled contribution: its host + its rules + its auth stance (F77).

type EntrySetter

type EntrySetter interface {
	Set(ctx context.Context, source string, entries []Entry) error
}

EntrySetter contributes ONE named source's edge entries to a shared edge table (ADR-0138). Router's Program is replace-all, so multiple independent route sources — the Route reconciler (user Routes) and the CatalogService reconciler (its node-private catalog::query PEP proxy) — would clobber each other if each called Program directly. They call Set instead. Set replaces THIS source's slice (nil/empty clears it); the implementation unions all sources and programs the table exactly once.

type Match

type Match struct {
	Namespace   v1.NamespaceName
	Function    v1.ObjectName
	StripPrefix string
	Auth        v1.AuthMode // the matched Route's auth stance (ADR-0113); "" ⇒ namespace default
	// Static is non-nil for a static backend (ADR-0120, F82): serve via internal/edge/static, no wake.
	Static *v1.StaticBackend
	// Upstream is non-empty for a node-private reverse-proxy backend (ADR-0138): the data-plane
	// reverse-proxies to it (no activator hop, no Function resolve). Trusted in-daemon target only.
	Upstream string
}

Match is the resolved target. StripPrefix is the matched rule's prefix the handler strips from the request path (empty for an Exact rule) to get the function-relative remainder.

type Programmer

type Programmer interface {
	Program(ctx context.Context, entries []Entry) error
}

Programmer is the replace-all sink the Aggregator drives — the edge Router's Program. Router satisfies it; the aggregator depends only on this narrow method.

type Router

type Router interface {
	// Program replaces the live table with the compiled Ready-route entries (mirrors the
	// gateway's replace-all ProgramRoutes).
	Program(ctx context.Context, entries []Entry) error
	// Resolve returns the matched target for (host, path, method), or ok=false ⇒ the caller 404s
	// (no activator wake). The matched entry carries its namespace, so no namespace input is needed.
	Resolve(host, path, method string) (Match, bool)
	// Hosts returns the distinct non-empty hosts currently programmed (F74 reads this for SNI).
	Hosts() []string
}

Router holds the compiled, replace-all Route table and resolves a request to a Match. Concurrency-safe.

func New

func New() Router

New returns an empty edge Router.

Jump to

Keyboard shortcuts

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