WIP: streamer Start takes a ctx; README and TODO
check / check (push) Canceled after 0s

Model: opus-5-5
This commit is contained in:
2026-10-14 13:04:16 +00:00
parent 50c8e9d276
commit 465e3ea292
5 changed files with 27 additions and 15 deletions
+14 -8
View File
@@ -273,24 +273,30 @@ standard: normalized scripts in `script/` are the entrypoints for the
development workflow, and the Makefile targets are thin shims that call
them. We provide:
- `script/bootstrap` — install all development dependencies (go,
golangci-lint, Go module download)
Tests and the linter run only in Docker, as the `test` and `lint` phases of the
`Dockerfile`; the image cannot be built unless both pass. Every `docker build`
in `script/` passes `--no-cache`, so each run executes every check.
- `script/bootstrap` — install all development dependencies (git, make, go, Go
module download); warns when docker is missing
- `script/setup` — make a fresh clone ready for development: runs
`script/bootstrap`, then `script/install-precommit`
- `script/projectname` — print the project name (used for the Docker
image tag)
- `script/test` — run the test suite
(`go test -short -timeout 30s -race -cover ./...`, verbose rerun on
failure). The `-short` flag skips the live-network integration test so the
default run is deterministic and offline.
- `script/lint` — run `go vet ./...` and `golangci-lint run`
- `script/test` — build the `test` phase alone, which runs
`go test -short -timeout 90s -race -cover ./...` (verbose rerun on failure).
The `-short` flag skips the live-network integration test so the run is
deterministic and offline.
- `script/lint` — build the `lint` phase alone, which runs golangci-lint
v2.14.0 with `.golangci.yml`
- `script/fmt` — format all code (writes)
- `script/fmt-check` — check formatting (read-only)
- `script/check` — run `script/test`, `script/lint`, and
`script/fmt-check`
- `script/docker` — build the Docker image tagged via
`script/projectname`
- `script/cibuild` — CI entrypoint: `docker build .`
- `script/cibuild` — CI entrypoint: runs `script/bootstrap` and
`script/check`, then builds the image
- `script/precommit` — pre-commit gate: `go mod tidy` + `go fmt` (must
not change files), then `script/check`
- `script/install-precommit` — install the git pre-commit hook that
+7 -2
View File
@@ -10,8 +10,9 @@
# Status
pre-1.0. No git tags. The Docker build runs the format check, the linter
and the tests, and the Gitea workflow runs that build on every push. The
pre-1.0. No git tags. The linter and the tests are phases of the Docker
build, and the Gitea workflow runs `script/cibuild` (the format check, both
phases, then the image) on every push. The
image sets memory ceilings for a 5 GiB container (README "Memory") and the
README says how to run it under upaas (README "Running under upaas"). A
35-hour run of `3898daa` on the live feed peaked at about 1 GiB, without a
@@ -27,6 +28,10 @@ real 5 GiB limit (https://git.eeqj.de/sneak/routewatch/issues/3).
# Completed Steps
- 2026-10-14: the shared files are re-vendored from `sneak/prompts` at
`dd4027b`: golangci-lint v2.14.0 and its configuration, lint and test as
separate uncached Dockerfile phases, agent guidance in `AGENTS.md`; the code
is fixed for what the new linter configuration finds (closes #52)
- 2026-10-03: `/api/v1/stats` serves the prefix distribution from memory,
seeded at startup and adjusted on every live-route write, so a request no
longer reads every live route (closes #30)
+1 -1
View File
@@ -31,7 +31,7 @@ func main() {
// Start streaming before any defer: log.Fatal exits without running
// deferred calls.
err := s.Start()
err := s.Start(context.Background())
if err != nil {
log.Fatal("Failed to start streamer:", err)
}
+1 -1
View File
@@ -109,7 +109,7 @@ func (rw *RouteWatch) Run(ctx context.Context) error {
// No longer need routing table handler - PrefixHandler maintains live_routes table
// Start streaming
err := rw.streamer.Start()
err := rw.streamer.Start(ctx)
if err != nil {
return err
}
+4 -3
View File
@@ -188,8 +188,9 @@ func (s *Streamer) RegisterRawHandler(handler RawMessageHandler) {
// Start begins streaming BGP updates from the RIS Live API in a background goroutine.
// It starts worker goroutines for each registered handler and manages automatic
// reconnection with exponential backoff on connection failures.
// Returns an error if the streamer is already running.
func (s *Streamer) Start() error {
// Returns an error if the streamer is already running. It streams until Stop:
// the end of ctx does not stop it.
func (s *Streamer) Start(ctx context.Context) error {
s.mu.Lock()
defer s.mu.Unlock()
@@ -197,7 +198,7 @@ func (s *Streamer) Start() error {
return errAlreadyRunning
}
ctx, cancel := context.WithCancel(context.Background())
ctx, cancel := context.WithCancel(context.WithoutCancel(ctx))
s.cancel = cancel
s.running = true