From 60262a8d9a0552701efa1a92e766cac590afb4bd Mon Sep 17 00:00:00 2001 From: Siddharth More Date: Wed, 29 Apr 2026 13:28:22 -0700 Subject: [PATCH] fix: clamp reconnect backoff delay and add observability logging --- engine.go | 10 ++++++---- localparticipant.go | 2 +- remoteparticipant.go | 1 + room.go | 3 +++ 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/engine.go b/engine.go index 0138853b..444aff2b 100644 --- a/engine.go +++ b/engine.go @@ -486,6 +486,7 @@ func (e *RTCEngine) createSubscriberPCLocked(configuration webrtc.Configuration) } else if c.Label() == lossyDataChannelName { e.lossyDCSub = c } else { + e.log.Warnw("received unknown data channel label, ignoring", nil, "label", c.Label()) return } c.OnMessage(e.handleDataPacket) @@ -626,6 +627,7 @@ func (e *RTCEngine) UnregisterTrackPublishedListener(cid string) { func (e *RTCEngine) handleDataPacket(msg webrtc.DataChannelMessage) { packet, err := e.readDataPacket(msg) if err != nil { + e.log.Warnw("failed to parse data packet", err, "isString", msg.IsString) return } identity := packet.ParticipantIdentity @@ -733,10 +735,10 @@ func (e *RTCEngine) handleDisconnect(fullReconnect bool) { } } - delay := time.Duration(reconnectCount*reconnectCount) * initialReconnectInterval - if delay > maxReconnectInterval { - break - } + // Quadratic backoff: delay grows as reconnectCount² × initialReconnectInterval. + // Clamped to maxReconnectInterval so a future increase to maxReconnectCount + // cannot produce unbounded delays or skip the final OnDisconnected call. + delay := min(time.Duration(reconnectCount*reconnectCount)*initialReconnectInterval, maxReconnectInterval) if reconnectCount < maxReconnectCount-1 { time.Sleep(delay) } diff --git a/localparticipant.go b/localparticipant.go index d634990e..63a31c65 100644 --- a/localparticipant.go +++ b/localparticipant.go @@ -747,7 +747,7 @@ func (p *LocalParticipant) updateSubscriptionPermissionLocked() { } if err := p.engine.SendSubscriptionPermission(p.subscriptionPermission); err != nil { - logger.Errorw( + p.log.Errorw( "could not send subscription permission", err, "participant", p.identity, "participantID", p.sid, diff --git a/remoteparticipant.go b/remoteparticipant.go index 5bdc3606..08efdab1 100644 --- a/remoteparticipant.go +++ b/remoteparticipant.go @@ -112,6 +112,7 @@ func (p *RemoteParticipant) addSubscribedMediaTrack( } time.Sleep(50 * time.Millisecond) } + p.engine.log.Warnw("timed out waiting for track publication metadata", nil, "trackSID", trackSID, "participant", p.Identity()) p.Callback.OnTrackSubscriptionFailed(trackSID, p) p.roomCallback.OnTrackSubscriptionFailed(trackSID, p) }() diff --git a/room.go b/room.go index 8842af9f..7c0d76fe 100644 --- a/room.go +++ b/room.go @@ -871,6 +871,7 @@ func (r *Room) OnDisconnected(reason DisconnectionReason) { } func (r *Room) OnRestarting() { + r.log.Infow("room connection restarting") r.setConnectionState(ConnectionStateReconnecting) r.callback.OnReconnecting() @@ -898,11 +899,13 @@ func (r *Room) OnRestarted( } func (r *Room) OnResuming() { + r.log.Infow("room connection resuming") r.setConnectionState(ConnectionStateReconnecting) r.callback.OnReconnecting() } func (r *Room) OnResumed() { + r.log.Infow("room connection resumed") r.setConnectionState(ConnectionStateConnected) r.callback.OnReconnected() r.sendSyncState()