Skip to content

End a gemdb run when its terminal closes - #137

Open
jgfoster wants to merge 2 commits into
mainfrom
james/hangup-ends-run
Open

jgfoster wants to merge 2 commits into
mainfrom
james/hangup-ends-run

Conversation

@jgfoster

Copy link
Copy Markdown
Member

Fixes #136.

The problem

Closing the terminal of gemdb app.py, or of Run Python File in GemDB, ended the bash wrapper but not topaz. Topaz carried on running the program out of sight, holding a session and, for a web app, its port. Measured on 4.0.0.a4 by closing a pty under it, as a terminal tab closes:

  • topaz ignores SIGHUP. Sent on its own, the signal had no effect.
  • A printing program is not ended either. Its writes to the dead terminal don't stop it.
  • finally never ran in either case.
  • SIGTERM ends topaz, but skips finally.

The fix

The wrapper's EXIT trap from #132 already runs on a hangup. It now checks whether topaz is still running (only when the run didn't finish, so a normal run does nothing extra):

  • SIGINT first, which is what Ctrl-C sends. The driver turns it into KeyboardInterrupt, the program's finally blocks run, and topaz logs out and exits. In the measurement that took under 250 ms, for a quiet program and a printing one.
  • SIGTERM if topaz hasn't gone within 10 seconds, for a program stuck somewhere a soft break doesn't reach.
  • Temporary files last. The driver writes the status file as it unwinds, and would otherwise recreate one the trap had just removed.

Topaz is found with pgrep -P $$ -x topaz. On a system without pgrep, nothing is found and the run behaves as before.

Tests

  • Integration. The hangup test from Keep topaz's own output off the terminal during a gemdb run #132 used to end topaz itself. It now closes a real pty through expect and requires:

    • topaz to end on its own,
    • the program's finally block to have run,
    • $TMPDIR to be empty.

    Against main's wrapper it fails in 15 s; with the fix it passes in about 1.2 s, and passed three runs in a row. The test resolves on expect's exit event rather than on its output closing, because a surviving topaz holds expect's pipes open and the test would otherwise time out instead of failing.

  • Unit. Checks that the trap is set before any temporary file exists, that it only looks for topaz while topaz is running, and that it sends SIGINT.

  • Suites. Lint, format, both typechecks, the unit suite (901) and the CLI integration file (23) pass on darwin-arm64. A full integration run under heavy machine load (load average around 11) failed: breakpoint.test.ts and spaceFull.test.ts timed out in setup, and two debugConsole.test.ts tests failed. Rerun on their own afterwards, all three files passed (45 tests). None of them runs the wrapper.

🤖 Generated with Claude Code

Closing the terminal of `gemdb app.py` ended the bash wrapper but not
topaz, which ignores SIGHUP: it carried on running the program with its
session (and a web app's port), out of sight. A program that kept printing
was not ended by its writes to the dead terminal either, and its finally
blocks never ran. Measured on 4.0.0.a4 by closing a pty under it.

The wrapper's EXIT trap, which bash runs on a hangup, now sends a topaz
that is still running SIGINT, what Ctrl-C sends: the program's finally
blocks run and topaz logs out and exits, within a quarter of a second in
the measurement. SIGTERM follows if it has not gone in ten seconds. The
temporary files are removed only after topaz has gone, since the driver
writes the status file as it unwinds.

The integration test now closes a real pty, as a terminal tab does, and
requires topaz to end on its own with the finally block run. Against the
previous wrapper it fails in 15 s rather than timing out: it waits on
expect's exit, not its pipes, which a surviving topaz holds open.

Fixes #136.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jgfoster
jgfoster removed the request for review from MatiasFernandez October 16, 2026 18:02
1.7.0 shipped without this change, so its changelog entry moves to
Unreleased.

This branch has not been deployed

No deployments
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.

Closing the terminal of a gemdb run leaves topaz running the program

2 participants