Skip to content

Commit 4967726

Browse files
committed
Fix ghost sessions: detect connection loss and clean up old session
- Add read deadline (3x ping interval) to detect dead connections - Force-close WebSocket on ping write error to unblock ReadJSON - Delete old session before creating new one in recreateSession
1 parent 488be1d commit 4967726

1 file changed

Lines changed: 16 additions & 2 deletions

File tree

websocket.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ func (d *Daemon) connectToRelay() {
5050

5151
wasConnected = true
5252

53+
// Set read deadline: if no message within 3 ping intervals, connection is dead
54+
conn.SetReadDeadline(time.Now().Add(PingInterval * 3))
55+
5356
// Cancel any previous ping goroutine
5457
d.mu.Lock()
5558
if d.pingCancel != nil {
@@ -81,6 +84,7 @@ func (d *Daemon) connectToRelay() {
8184
err := c.WriteJSON(Message{Type: "ping"})
8285
d.wsMu.Unlock()
8386
if err != nil {
87+
c.Close() // Force close to unblock ReadJSON
8488
return
8589
}
8690
}
@@ -105,9 +109,17 @@ func (d *Daemon) connectToRelay() {
105109
}
106110
}
107111

108-
// recreateSession creates a new session on the relay after the previous one was deleted.
109-
// Updates the daemon's session, token, and encryption state.
112+
// recreateSession creates a new session on the relay after connection loss.
113+
// Deletes the old session first to prevent ghost sessions, then creates a new one.
110114
func (d *Daemon) recreateSession() error {
115+
// Clean up old session (best effort - may already be gone via alarm)
116+
d.mu.RLock()
117+
oldSession := d.session
118+
d.mu.RUnlock()
119+
if oldSession != "" {
120+
d.relayClient.DeleteSession(oldSession)
121+
}
122+
111123
sshInfo := DetectSSHInfo()
112124
displayName := d.workDir
113125
if idx := strings.LastIndex(d.workDir, "/"); idx >= 0 {
@@ -138,6 +150,8 @@ func (d *Daemon) handleWebSocketMessages(conn *websocket.Conn) {
138150
if err := conn.ReadJSON(&msg); err != nil {
139151
return
140152
}
153+
// Reset read deadline on any successful read
154+
conn.SetReadDeadline(time.Now().Add(PingInterval * 3))
141155

142156
switch msg.Type {
143157
case "data":

0 commit comments

Comments
 (0)