SSH reconnect can replace an external T3 service with a competing managed runtime
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Problem
On a persistent SSH host that already runs the supported T3 systemd service, reconnecting from an updated desktop client can start a second T3 server and a second T3 Connect tunnel against the same base directory.
The failure is deterministic when launcher state says managed while server-runtime.json belongs to the launcher-managed process, or when a recorded external service is briefly unavailable during its own update. Requests and WebSockets can then land on different servers, producing intermittent reconnects and messages that appear to disappear.
Expected behavior
The supported external service remains the sole server/tunnel owner. The SSH launcher adopts its advertised port, records external ownership, and never replaces a temporarily restarting external service.
Proposed fix
The tested source change:
- distinguishes the launcher's own managed runtime record from a real external runtime;
- makes runtime-state cleanup conditional on PID/start-time ownership;
- preserves external ownership across transient unavailability; and
- adds regression coverage for adoption, reconnect, restart, and stale cleanup.
A focused PR follows.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the SSH launcher reconnect path and the launcher state, then inspect server-runtime.json handling and the systemd service ownership checks. Reproduce adoption, reconnect, transient restart, and stale-cleanup cases described in the issue. Done means the external service remains the sole server and tunnel owner, including while it is temporarily unavailable, with regression coverage for those cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100