Skip to content

Commit ba59b73

Browse files
committed
Add jitter and exponential backoff for resubscription when no data
1 parent 982c5b0 commit ba59b73

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

src/Tibber.Sdk/RealTimeMeasurementListener.cs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -450,9 +450,9 @@ private async Task TryReconnect()
450450
{
451451
try
452452
{
453-
var delay = GetDelaySeconds(failures);
454-
Trace.WriteLine($"retrying to connect in {delay} seconds");
455-
await Task.Delay(TimeSpan.FromSeconds(delay), _cancellationTokenSource.Token);
453+
var delay = GetDelay(failures);
454+
Trace.WriteLine($"retrying to connect in {delay.TotalSeconds} seconds");
455+
await Task.Delay(delay, _cancellationTokenSource.Token);
456456

457457
Trace.WriteLine("check there is a valid real time device");
458458
var homes = await _tibberApiClient.ValidateRealtimeDevice();
@@ -476,17 +476,21 @@ private void CheckDataStreamAlive(object state)
476476
ResubscribeStreams(
477477
c =>
478478
{
479-
var sinceLastMessageMs = (now - c.LastMessageReceivedAt).TotalMilliseconds;
480-
if (sinceLastMessageMs <= StreamReSubscriptionCheckPeriodMs)
479+
var sinceLastMessageMs = (now - c.LastMessageReceivedAt).TotalMilliseconds;
480+
if (sinceLastMessageMs <= GetDelay(c.ReconnectionAttempts).TotalMilliseconds)
481481
return false;
482482

483-
Trace.WriteLine($"home {c.Observable.HomeId} subscription {c.Observable.SubscriptionId}: no data received during last {sinceLastMessageMs:N0} ms; re-initialize data stream");
484-
c.LastMessageReceivedAt = now;
483+
Trace.WriteLine($"{now:yyyy-MM-dd HH:mm:ss.fff zzz} home {c.Observable.HomeId} subscription {c.Observable.SubscriptionId}: no data received during last {sinceLastMessageMs:N0} ms; re-initialize data stream");
484+
485+
if (c.LastMessageReceivedAt < c.LastReconnectionAttemptAt)
486+
c.ReconnectionAttempts++;
487+
c.LastReconnectionAttemptAt = now;
488+
485489
return true;
486490
});
487491
}
488492

489-
private static int GetDelaySeconds(int failures)
493+
private static TimeSpan GetDelay(int failures)
490494
{
491495
// Jitter of 5 to 60 seconds
492496
var jitter = Random.Next(5, 60);
@@ -496,7 +500,7 @@ private static int GetDelaySeconds(int failures)
496500

497501
// Max one day 60 * 60 * 24
498502
const double oneDayInSeconds = (double)60 * 60 * 24;
499-
return jitter + (int)Math.Min(delay, oneDayInSeconds);
503+
return TimeSpan.FromSeconds(jitter + (int)Math.Min(delay, oneDayInSeconds));
500504
}
501505

502506
private class WebSocketConnectionInitMessage
@@ -536,6 +540,8 @@ private class HomeStreamObserverCollection
536540
public readonly List<IObserver<RealTimeMeasurement>> Observers = new();
537541
public HomeRealTimeMeasurementObservable Observable;
538542
public DateTimeOffset LastMessageReceivedAt = DateTimeOffset.MaxValue;
543+
public DateTimeOffset LastReconnectionAttemptAt = DateTimeOffset.MaxValue;
544+
public int ReconnectionAttempts = 0;
539545
}
540546

541547
private class Unsubscriber : IDisposable

0 commit comments

Comments
 (0)