Files
crossbar/docs/plans/v1/07-main.md
T

68 lines
2.8 KiB
Markdown

# 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.