Skip to content

fix(hotblocks-retain): act on SIGTERM instead of waiting for the kill#104

Merged
mo4islona merged 1 commit into
masterfrom
fix/hotblocks-retain-sigterm
Jul 22, 2026
Merged

fix(hotblocks-retain): act on SIGTERM instead of waiting for the kill#104
mo4islona merged 1 commit into
masterfrom
fix/hotblocks-retain-sigterm

Conversation

@mo4islona

@mo4islona mo4islona commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

sqd-hotblocks-retain has no signal handling, and it runs as PID 1 in its container. Linux gives PID 1 no default signal dispositions: a signal with no handler installed is ignored, not fatal. SIGTERM therefore did nothing, and since the loop sleeps up to an hour between passes, SIGKILL at the end of the shutdown grace was the only thing that ever stopped this process.

That shows up as the container outliving its neighbours by the whole grace window and dying by signal, while the rest of the pod exits cleanly — pure dead time on every restart, and it grows with whatever grace the deployment needs.

The fix

Race the loop against a SIGTERM handler. Exiting immediately is safe here: retention is applied over HTTP and nothing is held locally, so a pass cut mid-flight is recomputed from the scheduler status on the next start.

SIGINT stays on the default handler, matching the hotblocks binary — a dev Ctrl-C is not PID 1, so it already works.

Verification

Ran the built binary against dead upstreams and signalled it: exits 0 having logged SIGTERM received, exiting, where an uninstalled handler would give 143 and no log line. The signal is caught mid-sleep, so the select races the timer correctly.

🤖 Generated with Claude Code

The process runs as PID 1 in its container, and Linux gives PID 1 no default
signal dispositions -- a signal with no handler installed is ignored outright
rather than being fatal. So SIGTERM did nothing here, and the loop sleeps up to
an hour between passes, which left SIGKILL at the termination grace as the only
way this ever stopped.

Measured on testnet-dev by polling a pod through its termination: this container
exits 137 while its neighbours exit 0 and 1. It cost 5s per rotation when the
grace was 5s and nobody noticed; now that hotblocks needs a real grace it holds
every pod for the full 60s, long after the drain is done at ~25s.

Exiting straight away is safe: retention is applied over HTTP and nothing is
held locally, so a pass cut mid-flight is simply recomputed from the scheduler
status on the next start. SIGINT is left on the default handler, matching the
hotblocks binary -- a dev Ctrl-C is not PID 1 and already works.
@mo4islona
mo4islona merged commit a48c17f into master Jul 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant