Skip to content

Interrupted remote session export leaks the fetch pipeline until its deadline #335

Description

@scgopi

Follow-up to #333 / #334 (remote session export, merged as 4715a30).

Defect

SessionTransplant.bounded() wraps a remote session fetch in a job-control group with a ten-minute watchdog and arms trap 'kill -TERM -- -$gc_p -$gc_w 2>/dev/null; exit 143' INT TERM HUP so that a signal to the shell takes the pipeline's and the watchdog's process groups with it. That trap never fires in practice:

  • Foundation Process spawns each /bin/sh in its own process group (measured: pgid == pid), so Ctrl-C in a Terminal reaches only the CLI's group, never the shell running the fetch.
  • Nothing in the codebase sends TERM to that shell either: runShell has no cancellation path, so an app-side cancellation (the export effect being torn down) leaves it running too.

Measured on the loopback ssh rig under a real pty, with the ssh mux master frozen to stall a fetch: the CLI died of SIGINT at 3s while 3 sh, 2 tar, 2 sleep 600 and the pipeline subshells survived to completion or to the 600s watchdog. The trap itself works when the shell is TERMed directly (measured: TERM to the shell leaves no ssh, tar, subshell or sleep behind), so the gap is only that no signal ever reaches it.

Impact: an interrupted or cancelled export leaks the fetch processes for up to ten minutes per loop. They exit on their own at the deadline; nothing is left permanently.

Fix idea

  1. A liveness guard in the watchdog instead of one long sleep: loop in short steps and kill -0 $PPID each step, killing both groups (-$gc_p -$gc_w) the moment the parent is gone. That covers every way the parent can die, including SIGKILL, without depending on a signal reaching the shell.
  2. process.terminate() on Task cancellation in runShell, so an app-side cancellation reaches the shell and the existing trap does its job.
  3. A SIGINT handler in the CLI's export path that terminates the in-flight fetches before exiting.

Test: the existing pipelineIsBoundedAndKillsItsOwnProcessGroupOnTheDeadline asserts the trap text; add one asserting the kill -0 $PPID guard, and re-measure on the rig with the mux master frozen: after Ctrl-C to the CLI, pgrep -f 'sleep 600' and the tar/ssh children should be gone within one guard step.

Reported by the RemoteExportVerify loop during the #334 review; measurements are theirs, reproduced with a forkpty harness (children need SIG_DFL dispositions).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions