relay: fix relays refusing to reconnect after initial connect fails

When isConnecting gets stuck (e.g. from silenced error 57 or lost
WebSocket events), reconnect() would bail out permanently. Instead of
unconditionally blocking on isConnecting, allow reconnect if the
connection attempt has gone stale (>5s with no socket response).

Closes: https://github.com/damus-io/damus/issues/3774

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
William Casarin
2026-05-18 11:53:57 -07:00
co-authored by Claude Opus 4.6
parent 07a7dbddc0
commit d2ef0ac3b1
+16 -5
View File
@@ -114,7 +114,7 @@ final class RelayConnection: ObservableObject {
guard let self else { guard let self else {
return return
} }
if err == nil { if err == nil {
self.last_pong = .now self.last_pong = .now
Log.info("Got pong from '%s'", for: .networking, self.relay_url.absoluteString) Log.info("Got pong from '%s'", for: .networking, self.relay_url.absoluteString)
@@ -214,7 +214,7 @@ final class RelayConnection: ObservableObject {
return return
} }
if nserr.domain == NSURLErrorDomain && nserr.code == -999 { if nserr.domain == NSURLErrorDomain && nserr.code == -999 {
// these aren't real error, it just means task was cancelled // these aren't real errors, it just means task was cancelled
return return
} }
DispatchQueue.main.async { DispatchQueue.main.async {
@@ -237,9 +237,9 @@ final class RelayConnection: ObservableObject {
} }
func reconnect() { func reconnect() {
guard !isConnecting && !isDisabled else { guard !isDisabled else {
self.log?.add("Cancelling reconnect, already connecting") self.log?.add("Cancelling reconnect, relay is disabled")
return // we're already trying to connect or we're disabled return
} }
guard !self.isConnected else { guard !self.isConnected else {
@@ -247,6 +247,17 @@ final class RelayConnection: ObservableObject {
return return
} }
// If we're already connecting, only force a reconnect if the
// attempt has gone stale (>5s with no response from the socket)
if isConnecting {
let elapsed = Date.now.timeIntervalSince1970 - last_connection_attempt
guard elapsed > 5 else {
self.log?.add("Cancelling reconnect, already connecting")
return
}
self.log?.add("Stale connection detected, forcing reconnect")
}
disconnect() disconnect()
connect() connect()
log?.add("Reconnecting...") log?.add("Reconnecting...")