Skip to content

fix(broker): free a lease whose attached process is gone (#104) - #108

Merged
T-Crypt merged 3 commits into
mainfrom
T-Crypt/fix-104
Oct 21, 2026
Merged

T-Crypt merged 3 commits into
mainfrom
T-Crypt/fix-104

Conversation

@T-Crypt

@T-Crypt T-Crypt commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Fixes #104, reported by @azrael-229.

The run's socket disconnect was the only signal that a lease ended. When the run's whole tree is killed (taskkill /F /T, a crash) and that disconnect never reaches the daemon, the lease stayed HOT with PIDS [] until a berth stop.

  • Every tick checks the attached process by PID plus start time. Seen gone on two consecutive ticks, with no container named and nothing of the run still on the card or alive as a descendant, the broker releases the lease exactly as a disconnect would: lease.orphaned, then lease.released and lease.freed once the card shows it gone. With a 2 s poll that is about 6 s instead of forever.
  • A reused PID (same number, new start time) counts as gone. A live process, a one-tick lookup miss, or a container lease is left alone. Nothing is signalled: Berth still never stops a process it did not start.
  • Descendant sets are pruned whenever one has entries, so a dead run's children clear from its lease. With no attached run and no entries the process table is still not read.
  • lease.orphaned shows as a warning in berth events and as ORPHANED in the harbor.

Tests (internal/broker/reap_test.go): dead pid released after two ticks and freed; reused PID; live pid with a lookup hiccup; container lease; a child outliving the wrapper released only after it exits.

Proof: build, gofmt, vet, go test ./..., -race -count=3 on the reaper tests, GOOS=windows build and vet, golangci-lint (0 issues).

The run's disconnect was the only signal that a lease ended. When the
whole run tree is killed and the disconnect never reaches the daemon,
the lease stayed granted with no process for as long as anyone looked.

Each tick now checks the attached process by PID and start time. Seen
gone on two ticks in a row, with no container named and nothing of the
run still counted on the card or alive as a descendant, the lease is
released the way a disconnect releases it, with a lease.orphaned event
first. A reused PID counts as gone. Nothing is signalled.

Descendant sets are now pruned while any has entries, so a dead run's
children clear from its lease; with no attached run and no entries the
process table is still not read.

Fixes #104.
@T-Crypt
T-Crypt merged commit 169c0c1 into main Oct 21, 2026
2 checks passed
@T-Crypt
T-Crypt deleted the T-Crypt/fix-104 branch October 21, 2026 14:07
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.

windows: lease not freed when the berth run process dies after attach (no reaper for a dead attached pid)

1 participant