Skip to content

Commit 1e37114

Browse files
committed
Fix errors on live control disconnect
1 parent 92250a0 commit 1e37114

File tree

5 files changed

+45
-23
lines changed

5 files changed

+45
-23
lines changed

Common/Websocket/WebsockBaseController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public virtual async ValueTask DisposeAsync()
102102
/// </summary>
103103
/// <returns></returns>
104104
[NonAction]
105-
public virtual ValueTask DisposeControllerAsync() => ValueTask.CompletedTask;
105+
protected virtual ValueTask DisposeControllerAsync() => ValueTask.CompletedTask;
106106

107107
/// <summary>
108108
/// Initial get request to the websocket route - rewrite to websocket connection

LiveControlGateway/Controllers/HubControllerBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ protected async Task SelfOnline(DateTimeOffset bootedAt, ushort? latency = null,
203203
}
204204

205205
/// <inheritdoc />
206-
public override ValueTask DisposeControllerAsync()
206+
protected override ValueTask DisposeControllerAsync()
207207
{
208208
Logger.LogTrace("Disposing controller timer");
209209
_keepAliveTimeoutTimer.Dispose();

LiveControlGateway/Controllers/HubV2Controller.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ public override ValueTask OtaInstall(SemVersion version)
226226

227227

228228
/// <inheritdoc />
229-
public override async ValueTask DisposeControllerAsync()
229+
protected override async ValueTask DisposeControllerAsync()
230230
{
231231
await _pingTimer.DisposeAsync();
232232
await base.DisposeControllerAsync();

LiveControlGateway/Controllers/LiveControlController.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public LiveControlController(
8888
}
8989

9090

91-
private bool _unregistered;
91+
private volatile bool _unregistered;
9292

9393
/// <inheritdoc />
9494
protected override async Task UnregisterConnection()
@@ -566,13 +566,36 @@ await QueueMessage(new LiveControlResponse<LiveResponseType>
566566
}
567567
});
568568
}
569+
570+
/// <summary>
571+
/// Called by a hub lifetime when the hub is disconnected and this controller needs to die
572+
/// </summary>
573+
[NonAction]
574+
public async Task HubDisconnected()
575+
{
576+
_unregistered = true;
577+
578+
Logger.LogTrace("Hub disconnected, disposing controller");
579+
try
580+
{
581+
await SendWebSocketMessage(new LiveControlResponse<LiveResponseType>
582+
{
583+
ResponseType = LiveResponseType.DeviceNotConnected,
584+
}, WebSocket!, LinkedToken);
585+
}
586+
catch (Exception e)
587+
{
588+
// We don't really care if this fails
589+
Logger.LogDebug(e, "Error while sending disconnect message");
590+
}
591+
await DisposeAsync();
592+
}
569593

570594
/// <inheritdoc />
571-
public override async ValueTask DisposeControllerAsync()
595+
protected override async ValueTask DisposeControllerAsync()
572596
{
573597
Logger.LogTrace("Disposing controller timer");
574598
_pingTimer.Dispose();
575-
await UpdateConnectedState(false);
576599
await base.DisposeControllerAsync();
577600
}
578601
}

LiveControlGateway/LifetimeManager/HubLifetime.cs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,12 @@ public HubLifetime([Range(1, 10)] byte tps, IHubController hubController,
9090
{
9191
using (await _liveControlClientsLock.LockAsyncScoped())
9292
{
93-
if (_liveControlClients.Contains(controller))
93+
if (_liveControlClients.Contains(controller))
9494
{
9595
_logger.LogWarning("Client already registered, not sure how this happened, probably a bug");
9696
return null;
9797
}
98-
98+
9999
_liveControlClients = _liveControlClients.Add(controller);
100100
}
101101

@@ -120,21 +120,21 @@ public async Task<bool> RemoveLiveControlClient(LiveControlController controller
120120

121121
private async Task DisposeLiveControlClients()
122122
{
123-
foreach (var client in _liveControlClients)
123+
ImmutableArray<LiveControlController> liveControlClients;
124+
using (await _liveControlClientsLock.LockAsyncScoped())
124125
{
125-
try
126-
{
127-
await client.DisposeAsync();
128-
}
129-
catch (Exception e)
130-
{
131-
_logger.LogError(e, "Error disposing live control client");
132-
}
126+
liveControlClients = _liveControlClients;
127+
_liveControlClients = _liveControlClients.Clear(); // Returns just an empty lol
133128
}
134129

135-
using (await _liveControlClientsLock.LockAsyncScoped())
130+
try
131+
{
132+
await Task.WhenAll(liveControlClients.Select(client => client.HubDisconnected()));
133+
}
134+
catch (Exception e)
136135
{
137-
_liveControlClients = _liveControlClients.Clear();
136+
// We dont expect any errors here, but if there is a bug then this might happen, and it would be cat
137+
_logger.LogError(e, "Error disposing live control client");
138138
}
139139
}
140140

@@ -160,7 +160,7 @@ public async Task<bool> InitAsync(CancellationToken cancellationToken)
160160
#pragma warning restore CS4014
161161

162162
_state = HubLifetimeState.Idle; // We are fully setup, we can go back to idle state
163-
163+
164164
return true;
165165
}
166166

@@ -269,7 +269,7 @@ public async Task UpdateDevice()
269269
{
270270
await using var db = await _dbContextFactory.CreateDbContextAsync(_cancellationSource.Token);
271271
await UpdateShockers(db, _cancellationSource.Token);
272-
272+
273273
foreach (var websocketController in _liveControlClients)
274274
await websocketController.UpdatePermissions(db);
275275
}
@@ -429,11 +429,10 @@ public async ValueTask DisposeAsync()
429429
{
430430
if (_disposed) return;
431431
_disposed = true;
432-
432+
433433
await _cancellationSource.CancelAsync();
434434
await DisposeLiveControlClients();
435435
}
436-
437436
}
438437

439438
/// <summary>

0 commit comments

Comments
 (0)