Skip to content

fix(filler): close the ship socket before a hard exit - #198

Merged
robrigo merged 1 commit into
mainfrom
fix/close-ship-socket-on-hard-exit
Aug 25, 2026
Merged

fix(filler): close the ship socket before a hard exit#198
robrigo merged 1 commit into
mainfrom
fix/close-ship-socket-on-hard-exit

Conversation

@robrigo

@robrigo robrigo commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Why

The filler leaves on process.exit(1) from an unhandled rejection, an uncaught exception, and both watchdog paths, and none of them closed the state_history websocket first. Abandoning a socket the client could have closed leaves the node holding a half-open session until it works out the peer is gone, so a filler restarted straight after a crash opens a second session beside the first.

A filler caught in a crash-restart loop shows the shape of it: an immediate restart ran at the live chain rate with [DS:0|SH:0], while the same restart after a short pause ran at full speed with SH climbing into the twenties. The node half of that is inference and not something measured here, and transient node load is not ruled out. The abandoned socket is wrong on its own terms regardless, which is what this fixes.

Both watchdog paths already pause before exiting, so they take the full graceful stop and the close frame leaves while the process is still alive. The crash handlers cannot safely await anything, since a wedged reader is exactly what they exist to escape, so they send the close frame and exit on a short fixed timer instead.

Validation

pnpm test goes from 419 passing to 421, 37 pending unchanged, with the two added tests covering the new seam: that it stops the reader, and that a rejection from the stop path cannot hold up the exit. pnpm check-types and pnpm lint are clean. The crash-handler path in src/bin/filler.ts is not unit tested, because the module forks a cluster at import time; the change there is confined to the close call and the timer.

The filler leaves on process.exit(1) from an unhandled rejection, an
uncaught exception, and both watchdog paths, and none of them closed the
state_history websocket first. Abandoning a socket the client could have
closed leaves the node holding a half-open session until it works out
the peer is gone, so a filler restarted straight after a crash opens a
second session beside the first.

A repeating foreign-key crash showed the shape of it in the field: an
immediate restart crawled at the live chain rate while the same restart
with a short pause ran at full speed. The node half of that is inference
rather than something measured, but the abandoned socket is wrong on its
own terms.

Both watchdog paths already pause before exiting, so they take the full
graceful stop and the close frame leaves while the process is still
alive. The crash handlers cannot await anything safely, since a wedged
reader is exactly what they exist to escape, so they send the frame and
exit on a short fixed timer instead.

Signed-off-by: Rob Konsdorf <rob@facings.io>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ensures filler shutdown paths close the state-history websocket before terminating.

Changes:

  • Gracefully stops readers before watchdog exits.
  • Adds delayed crash-handler exits after closing SHIP sockets.
  • Tests successful and rejected reader shutdowns.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
src/filler/filler.ts Adds safe reader shutdown before watchdog exits.
src/filler/filler.test.ts Tests shutdown success and failure handling.
src/bin/filler.ts Closes active SHIP sockets before crash exits.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@robrigo
robrigo merged commit e5c18f5 into main Aug 25, 2026
8 checks passed
@robrigo robrigo mentioned this pull request Aug 25, 2026
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.

2 participants