4.2 KiB
v2.2 task 01: route templates
Branch: v2.2 (git switch -c v2.2 master if it does not exist, else git switch v2.2; git status --short must be empty, otherwise stop)
Commit subject: Route templates: a route named x-* serves any request route x-<something>
Goal
PLAN.md §4a gives every OpenCode instance its own route (CROSSBAR_ROUTE="$(basename "$PWD")-$$"),
but the config only knows explicit [routes.NAME] tables and everything else is 404 unknown route. After this task a route whose name ends in -* is a template: a request route that
starts with the part before the star, with something non-empty after it, uses that route's hosts,
default model and peers. Leases and accounting stay keyed by the concrete route name, so two
instances never share a lease and each has its own usage row.
Files
- Copy:
internal/config/config_v22_test.go(itsTestWakeBroadcastsbelongs to task 02 and will fail to compile until then — see step 2),internal/proxy/template_test.go,internal/admin/admin_template_test.go - Modify:
internal/config/config.go,internal/proxy/proxy.go,internal/admin/admin.go,internal/admin/admin_ops.go,cmd/crossbar/main.go(the identity middleware's route→peers lookup),docs/implementer-log.md
Interfaces
package config
// Route resolves a request route name: an exact entry wins; else the longest template
// "<prefix>-*" whose prefix (including the dash) starts name with a non-empty remainder;
// else ok is false. key is the config key that matched (the template's name for a template).
// A name that is not a valid route name (the pattern below) or contains '*' never matches.
func (c *Config) Route(name string) (r Route, key string, ok bool)
Rules:
- Config route keys match
^[a-z0-9][a-z0-9-]*$(as before) or^[a-z0-9][a-z0-9-]*-\*$(a template). Anything else with a*isroutes.<name>: must match …as today. A template alone satisfies "at least one route". - Resolution order: exact, then longest matching template, then none.
- The proxy resolves both the path form and the
X-Crossbar-Routeheader form throughcfg.Route; the concrete name (not the template key) is the route used for leases, accounting rows, logs and headers. The "conflicting route" check compares concrete names. - Admin:
POST /_crossbar/routes/{route}resolves throughcfg.Route— a concrete route under a template can be pinned/released even before its first request; the template name itself is404 unknown route.GET /_crossbar/routeslists config keys (templates under their own name) and, for a template, the leases of every concrete route it matches. main.go: the identity middleware'sfunc(route string) ([]string, bool)usescfg.Route.
Steps
- 1. Branch as above; copy the three given tests.
- 2. See them fail.
config_v22_test.goalso referencesWake.Addresses()(task 02); until then run the config package with-run 'TestRouteTemplate'after adding a temporary stub? No — do not add stubs. Instead implement task 01 and rungo test -race -count=1 ./internal/proxy/ ./internal/admin/for the behaviour, andgo vet ./internal/config/will fail only on the missingAddressesmethod until task 02: that is expected and is the one allowed red at the end of this task. Say so in the log row. - 3.
config.go: the template regex,Route(). 4.proxy.goroute resolution. 5.admin.go/admin_ops.go. 6.main.go. - 7.
gofmt -w;go test -race -count=1 ./internal/proxy/ ./internal/admin/ ./internal/health/ ./internal/wake/→ok. - 8. Row
v2.2/01-route-templates; commit (the gate runs green after task 02).
git add internal/config internal/proxy internal/admin cmd/crossbar docs/implementer-log.md
git commit
Done when
TestRouteTemplateServesConcreteRoutesandTestRoutesViewAndPinWithTemplatespass under-race; every earlier proxy/admin test still passes; given files byte-identical; no file over 400 lines.internal/configis red only onAddresses(task 02).
Stop and report if
- Passing needs a change to any earlier given test.
- The 400-line limit forces
proxy.goapart: say which split you propose before doing it.