Skip to content

Commit

Permalink
Fix multi-threading crash to desktop when publishing ATIS to hub
Browse files Browse the repository at this point in the history
  • Loading branch information
justinshannon committed Jan 17, 2025
1 parent 10b1d8f commit 7442f44
Showing 1 changed file with 37 additions and 14 deletions.
51 changes: 37 additions & 14 deletions vATIS.Desktop/Ui/ViewModels/AtisStationViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ public class AtisStationViewModel : ReactiveViewModelBase, IDisposable
private CancellationTokenSource _cancellationToken;
private AtisPreset? _previousAtisPreset;
private DecodedMetar? _decodedMetar;
private IDisposable? _publishAtisTimer;
private bool _isPublishAtisTriggeredInitially;
private Timer? _publishAtisTimer;
private int _notamFreeTextOffset;
private int _airportConditionsFreeTextOffset;
private string? _id;
Expand Down Expand Up @@ -577,6 +576,9 @@ public void Dispose()
_networkConnection.KillRequestReceived -= OnKillRequestedReceived;
}

_publishAtisTimer?.Dispose();
_publishAtisTimer = null;

DecrementAtisLetterCommand.Dispose();
AcknowledgeOrIncrementAtisLetterCommand.Dispose();
AcknowledgeAtisUpdateCommand.Dispose();
Expand Down Expand Up @@ -850,9 +852,10 @@ private async void HandleNetworkStatusChanged(NetworkConnectionStatus status)
Math.Max(_sessionManager.CurrentConnectionCount - 1, 0);
await _voiceServerConnection.RemoveBot(_networkConnection.Callsign);
_voiceServerConnection?.Disconnect();

// Dispose of the ATIS publish timer to stop further publishing.
_publishAtisTimer?.Dispose();
_publishAtisTimer = null;
_isPublishAtisTriggeredInitially = false;
}
catch (Exception ex)
{
Expand Down Expand Up @@ -1131,20 +1134,40 @@ private async Task PublishAtisToWebsocket(ClientMetadata? session = null)

private async Task PublishAtisToHub()
{
await _atisHubConnection.PublishAtis(new AtisHubDto(_atisStation.Identifier, _atisStation.AtisType,
AtisLetter, Metar?.Trim(), Wind?.Trim(), Altimeter?.Trim()));
// Publish ATIS immediately
await PublishAtis();

// Dispose of the existing timer to start a new one.
_publishAtisTimer?.Dispose();
_publishAtisTimer = null;

// Set up a new timer to re-publish ATIS every 3 minutes.
// The Timer callback uses an async void method to handle exceptions explicitly.
_publishAtisTimer = new Timer(PublishAtisTimerCallback, null, TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(3));
}

// Setup timer to re-publish ATIS every 3 minutes to keep it active in the hub cache
if (!_isPublishAtisTriggeredInitially)
private async void PublishAtisTimerCallback(object? state)
{
try
{
await PublishAtis();
}
catch (Exception ex)
{
_isPublishAtisTriggeredInitially = true;
Log.Error(ex, "Failed to publish ATIS to hub");
}
}

// ReSharper disable once AsyncVoidLambda
_publishAtisTimer = Observable.Interval(TimeSpan.FromMinutes(3)).Subscribe(async _ =>
{
await _atisHubConnection.PublishAtis(new AtisHubDto(_atisStation.Identifier, _atisStation.AtisType,
AtisLetter, Metar?.Trim(), Wind?.Trim(), Altimeter?.Trim()));
});
private async Task PublishAtis()
{
try
{
await _atisHubConnection.PublishAtis(new AtisHubDto(_atisStation.Identifier, _atisStation.AtisType,
AtisLetter, Metar?.Trim(), Wind?.Trim(), Altimeter?.Trim()));
}
catch (Exception ex)
{
Log.Error(ex, "Failed to publish ATIS to hub");
}
}

Expand Down

0 comments on commit 7442f44

Please sign in to comment.