v1 plan: split task 06 into admin (06) and main wiring (07); smoke becomes 08; note the finding
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
# v1 task 07: wire the store, leases and limiter into `crossbar`
|
||||
|
||||
**Branch:** `v1` (run `git switch v1`; `git status --short` must be empty, otherwise stop)
|
||||
**Commit subject:** `Wire the store, lease table and limiter into crossbar`
|
||||
|
||||
## Goal
|
||||
|
||||
`cmd/crossbar` opens the SQLite store, builds the lease table and the limiter from the config,
|
||||
registers every route's hosts, serves the v1 proxy and admin, runs idle expiry and pruning in
|
||||
the background, records poller observations, and shuts down cleanly. `PLAN.md` §5–§7a.
|
||||
|
||||
## Files
|
||||
|
||||
- Modify: `cmd/crossbar/main.go`, `docs/implementer-log.md`
|
||||
|
||||
## Rules
|
||||
|
||||
`cmd/crossbar/main.go` (keep the v0 shape: `-config`, slog to stderr, signal context, graceful shutdown):
|
||||
|
||||
1. After `config.Load`: `st, err := store.Open(cfg.DB)`; error → `crossbar: …` on stderr, exit 1. Close it on the way out.
|
||||
2. `table := health.New(bases, cfg.PollInterval.Duration, nil)`; `go table.Run(ctx)`.
|
||||
3. `hosts := proxy.HostView(table, cfg)`; `lim := limiter.New()` and, for every host and model in
|
||||
`cfg.Hosts`, `lim.Configure(host, model, m.Parallel, cfg.QueueMax)`.
|
||||
4. `leases, err := lease.New(st, hosts, proxy.Chooser(cfg, table, lim), cfg.LeaseIdle.Duration)`;
|
||||
error → exit 1. Then `for name, rt := range cfg.Routes { leases.Candidates(name, rt.Hosts) }`.
|
||||
5. `mux.Handle("/_crossbar/", admin.Handler(cfg, table, leases, lim, st, hosts))`;
|
||||
`mux.Handle("/", proxy.New(cfg, table, leases, lim, st, log))`.
|
||||
6. Background goroutines until `ctx` is done: every minute `leases.ExpireIdle(time.Now())`; every
|
||||
hour `st.Prune(time.Now(), cfg.Retention.Duration)` (log the count); every `poll_interval`
|
||||
read `table.All()` and `st.RecordHostHealth` one row per host. Log errors, never exit on them.
|
||||
7. Shutdown as v0 (`srv.Shutdown` with a 10 s timeout), then `st.Close()`. Exit 0.
|
||||
|
||||
## Steps
|
||||
|
||||
- [ ] **1.** `git switch v1`; `git status --short` empty.
|
||||
- [ ] **2. Write `main.go`.** `gofmt -w cmd/`.
|
||||
- [ ] **3. Build and run for three seconds.**
|
||||
|
||||
```sh
|
||||
make build
|
||||
timeout --preserve-status --signal=TERM 3 bin/crossbar -config example.toml; echo "exit=$?"
|
||||
ls crossbar.db* && rm -f crossbar.db crossbar.db-wal crossbar.db-shm
|
||||
```
|
||||
|
||||
Expected: `listening`, `shutting down`, `exit=0`; the SQLite file existed (then removed). Then:
|
||||
|
||||
```sh
|
||||
bin/crossbar -config /nonexistent.toml; echo "exit=$?"
|
||||
```
|
||||
|
||||
Expected: `crossbar: config: open /nonexistent.toml: no such file or directory`, `exit=1`.
|
||||
|
||||
- [ ] **4. Run the gate.** `make gate`. Expected last line: `gate: ok`.
|
||||
- [ ] **5. Log and commit.** Row `v1/07-main`.
|
||||
|
||||
```sh
|
||||
git add cmd/crossbar docs/implementer-log.md
|
||||
git commit
|
||||
```
|
||||
|
||||
## Done when
|
||||
|
||||
- The three-second run exits 0 and created the db; the missing-config run exits 1; `make gate` prints `gate: ok`.
|
||||
|
||||
## Stop and report if
|
||||
|
||||
- `bin/crossbar` does not exit 0 on SIGTERM within the timeout.
|
||||
Reference in New Issue
Block a user