Handle SIGINT/SIGTERM gracefully during scan #5

Open
opened 2026-08-09 03:43:40 +02:00 by clawbot · 0 comments
Collaborator

There is no signal handling anywhere in the repo — os/signal is never imported. runScan (scan.go:53-78) installs no handler, the walk dispatcher and hash worker pools (scan.go:373, scan.go:590-613) have no cancellation path, and progress.go never finishes the bar or restores the terminal line.

The headline use case is a multi-hour scan of ~10M files / ~150 TB, run from cron or interactively. An operator who interrupts at hour three kills the process mid-render: no final summary, no clean terminal, no controlled commit of the in-flight batch. Batched commits mean most work survives, but the shutdown is uncontrolled and undocumented.

Definition of done

  1. scan installs signal.NotifyContext for SIGINT and SIGTERM; the resulting ctx is threaded as the first argument through the walk dispatcher, the hash pool and the database writes, per the Go styleguide.
  2. On cancellation the pools drain promptly, the in-flight batch is committed (not discarded — partial progress is the documented contract), and the database is closed.
  3. The active progress display is finished so the terminal is left clean.
  4. A scan: interrupted after N files line goes to stderr and the process exits 1. README §Error handling documents the interrupt behaviour and the exit code.
  5. A test calls the scan entrypoint with an already-cancelled context and asserts it returns promptly, leaves a valid database, and that a subsequent scan converges normally.
  6. make check green.

Depends on #4 (the database must actually close) and overlaps #6 (the pools must be cancellable).

There is no signal handling anywhere in the repo — `os/signal` is never imported. `runScan` (`scan.go:53-78`) installs no handler, the walk dispatcher and hash worker pools (`scan.go:373`, `scan.go:590-613`) have no cancellation path, and `progress.go` never finishes the bar or restores the terminal line. The headline use case is a multi-hour scan of ~10M files / ~150 TB, run from cron or interactively. An operator who interrupts at hour three kills the process mid-render: no final summary, no clean terminal, no controlled commit of the in-flight batch. Batched commits mean most work survives, but the shutdown is uncontrolled and undocumented. ## Definition of done 1. `scan` installs `signal.NotifyContext` for SIGINT and SIGTERM; the resulting `ctx` is threaded as the first argument through the walk dispatcher, the hash pool and the database writes, per the Go styleguide. 2. On cancellation the pools drain promptly, the in-flight batch is committed (not discarded — partial progress is the documented contract), and the database is closed. 3. The active progress display is finished so the terminal is left clean. 4. A `scan: interrupted after N files` line goes to stderr and the process exits 1. README §Error handling documents the interrupt behaviour and the exit code. 5. A test calls the scan entrypoint with an already-cancelled context and asserts it returns promptly, leaves a valid database, and that a subsequent scan converges normally. 6. `make check` green. Depends on #4 (the database must actually close) and overlaps #6 (the pools must be cancellable).
clawbot added this to the 1.0.0 milestone 2026-08-09 03:43:40 +02:00
Sign in to join this conversation.