68 lines
2.8 KiB
Markdown
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.
|