Preserve live remote PTYs when relay lease disappears - #9760
Conversation
📝 WalkthroughWalkthroughThe persistent daemon now tracks connections and PTY sessions together when evaluating shutdown. It preserves detached PTYs after lease removal, retires only when activity is empty, logs exit reasons, and adds lifecycle tests for lease loss and idle timeout. ChangesPersistent daemon lifecycle
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant PersistentDaemon
participant PTYSession
participant SlotLease
Client->>PersistentDaemon: Disconnect stdio
PersistentDaemon->>PTYSession: Check active sessions
PersistentDaemon->>SlotLease: Observe lease removal
SlotLease-->>PersistentDaemon: Lease absent
PersistentDaemon-->>Client: Preserve detached PTY
Client->>PersistentDaemon: Reconnect and reattach
Client->>PTYSession: Close PTY
PersistentDaemon-->>PersistentDaemon: Log lease-removal exit
Possibly related PRs
Suggested reviewers: Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error)
✅ Passed checks (24 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@daemon/remote/cmd/cmuxd-remote/main_test.go`:
- Around line 2068-2073: Update the automatic-exit log assertions in
daemon/remote/cmd/cmuxd-remote/main_test.go lines 2068-2073 and
daemon/remote/cmd/cmuxd-remote/persistent_lifecycle_test.go lines 508-512 to
extract the time= field and parse it with time.RFC3339Nano, while preserving
validation of the existing reason and activity counts.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: a36c1257-8b9c-4ffe-b7c0-6175b28799af
📒 Files selected for processing (6)
daemon/remote/README.mddaemon/remote/cmd/cmuxd-remote/main.godaemon/remote/cmd/cmuxd-remote/main_test.godaemon/remote/cmd/cmuxd-remote/persistent_lifecycle.godaemon/remote/cmd/cmuxd-remote/persistent_lifecycle_test.godocs/remote-daemon-spec.md
Summary
daemon.logRoot cause
The relay
.slotfile andactiveConnectionsdescribe transport ownership, but the lease-gone branch used those transport facts as authority to return from the daemon and runhub.closeAll(). That bypassed the live-session guard already used by the empty-idle branch and terminated persistent PTYs during a reconnect gap.Authenticated
daemon.shutdownremains intentionally destructive for final workspace cleanup. Passive lease observation now only makes an otherwise empty daemon eligible to retire.Test-first proof
The branch preserves red-before-green history:
2dd592e8eechanges only tests. On the old production code,TestPersistentDaemonPreservesActivePTYAfterObservedSlotLeaseDisappearsfailed withpersistent daemon retired while its detached PTY was still active; the empty-idle test also exposed the missing lifecycle log.06e27e445bimplements the shared automatic-retirement gate and lifecycle diagnostics. The regression reconnects to the same detached PTY after lease removal, then proves the daemon retires only afterpty.closeleaves the hub empty.Verification
go test ./... -count=1 -timeout 10mgo vet ./...gofmtandgit diff --checkgo test -race ./...was attempted twice. Each run hit a different pre-existing short-deadline integration timeout under race load; both the affected shutdown sibling and every lifecycle test in this PR pass together under focused race execution.Scope
No Swift files or warning/file-length budget files change. Explicit workspace shutdown behavior is unchanged.
Closes #9706
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Note
Medium Risk
Changes persistent SSH PTY daemon lifecycle and retirement timing on the remote host; behavior is well-tested but affects reconnect gaps and workspace teardown boundaries.
Overview
Fixes premature persistent daemon shutdown when the relay
.slotlease disappears while a detached PTY is still running.Passive retirement now uses one gate: automatic exit only when stdio connections and live PTY sessions (including sessions mid-teardown) are both zero. Lease loss alone no longer tears down live detached sessions; they survive until exit, explicit
pty.close, or the empty idle timeout. Authenticateddaemon.shutdownfor workspace cleanup is unchanged.The PTY hub counts sessions through teardown completion (
sessionTeardownCount/WaitGroup) so retirement cannot race idle reaping. Automatic exits log RFC3339Nano timestamps, reason (slot_lease_removedorempty_idle_timeout), and activity counts todaemon.log. Docs describe passive lease policy and lifecycle diagnostics.Reviewed by Cursor Bugbot for commit e539849. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Preserves live remote PTYs when a relay slot lease disappears and retires the daemon only when it’s truly empty (no stdio and no live or tearing‑down PTY sessions). Adds timestamped exit logs with reason and activity counts, and tightens idle/lease checks and docs on passive lease policy. Addresses #9706.
Bug Fixes
~/.cmux/relay/<port>.slotlease loss; retirement requires zero stdio connections and zero PTY sessions, including sessions mid‑teardown.closeAllblocks until processes and PTY files close, and the idle reaper counts a session as active until teardown completes. Authenticateddaemon.shutdownstays destructive.Refactors
slot_lease_removedorempty_idle_timeout), and activity counts todaemon.log.Written for commit e539849. Summary will update on new commits.
Summary by CodeRabbit
Bug Fixes
Documentation
Diagnostics