v1 plan: fix spread test config, queue test read, admin pin via lease.Candidates; note the findings
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,15 @@ builds the lease table and limiter, runs idle expiry and pruning, and shuts down
|
||||
|
||||
## Interfaces
|
||||
|
||||
`internal/lease` gains one method — the only change to that package allowed in this task:
|
||||
|
||||
```go
|
||||
// Candidates records hosts as seen for route (idempotent), so Pin can accept a host the route
|
||||
// is configured for before any request has used it. cmd/crossbar calls it for every route at
|
||||
// start; the admin handler calls it before Pin.
|
||||
func (t *Table) Candidates(route string, hosts []string)
|
||||
```
|
||||
|
||||
`internal/admin`, package `admin`:
|
||||
|
||||
```go
|
||||
@@ -48,7 +57,9 @@ Endpoints (all JSON unless said; errors `{"error":"…"}`; wrong method → 405
|
||||
|
||||
- `GET /_crossbar/hosts` → `map[string]HostView`.
|
||||
- `GET /_crossbar/routes` → `map[string]RouteView` from config + `lt.Snapshot()` + `lt.Pinned`.
|
||||
- `POST /_crossbar/routes/{route}` body `{"host":"…","pin":true}` → `lt.Pin(route, host, now)`;
|
||||
- `POST /_crossbar/routes/{route}` body `{"host":"…","pin":true}`: first check `host` is one of
|
||||
`cfg.Routes[route].Hosts` (else **404**), then `lt.Candidates(route, cfg.Routes[route].Hosts)` so
|
||||
the table knows them even if no request has used the route yet, then `lt.Pin(route, host, now)`;
|
||||
`{"release":true}` → `lt.Release(route)` **and** `lt.Unpin(route)`. Unknown route → 404;
|
||||
`lt.Pin` returning `ErrUnknownHost` → 404; not JSON, neither form, or both forms at once,
|
||||
or `pin` without `host` → 400. Answer `{"ok":true}` (plus `"released": n` for a release).
|
||||
@@ -88,6 +99,7 @@ Endpoints (all JSON unless said; errors `{"error":"…"}`; wrong method → 405
|
||||
- After `config.Load`: `store.Open(cfg.DB)` (error → exit 1 `crossbar: …`); `defer st.Close()`.
|
||||
- `hosts := proxy.HostView(table, cfg)`; `lim := limiter.New()` configured for every host/model
|
||||
from config with `cfg.QueueMax`; `leases, err := lease.New(st, hosts, proxy.Chooser(cfg, table, lim), cfg.LeaseIdle.Duration)`.
|
||||
- `for name, rt := range cfg.Routes { leases.Candidates(name, rt.Hosts) }`.
|
||||
- `proxy.New(cfg, table, leases, lim, st, log)`; `admin.Handler(cfg, table, leases, lim, st, hosts)`.
|
||||
- Background loops until ctx is done: every minute `leases.ExpireIdle(time.Now())`; every hour
|
||||
`st.Prune(time.Now(), cfg.Retention.Duration)`; after every poll round the health table's
|
||||
@@ -112,7 +124,7 @@ Expected: `listening`, `shutting down`, `exit=0`; the SQLite file was created (t
|
||||
- [ ] **6. Run the gate.** `make gate`. **7. Log and commit.** Row `v1/06-admin-main`.
|
||||
|
||||
```sh
|
||||
git add internal/admin internal/store cmd/crossbar example.toml docs/implementer-log.md
|
||||
git add internal/admin internal/store internal/lease cmd/crossbar example.toml docs/implementer-log.md
|
||||
git commit
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user