potential resolve disposal crashes and race conditions
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using LightlessSync.API.Dto.User;
|
using LightlessSync.API.Dto.User;
|
||||||
using LightlessSync.Services.ActorTracking;
|
using LightlessSync.Services.ActorTracking;
|
||||||
using LightlessSync.Services.Mediator;
|
using LightlessSync.Services.Mediator;
|
||||||
@@ -33,6 +33,7 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
|
|||||||
private const int _maxQueueSize = 100;
|
private const int _maxQueueSize = 100;
|
||||||
|
|
||||||
private volatile bool _batchRunning = false;
|
private volatile bool _batchRunning = false;
|
||||||
|
private volatile bool _disposed = false;
|
||||||
|
|
||||||
public IReadOnlyDictionary<string, BroadcastEntry> BroadcastCache => _broadcastCache;
|
public IReadOnlyDictionary<string, BroadcastEntry> BroadcastCache => _broadcastCache;
|
||||||
public readonly record struct BroadcastEntry(bool IsBroadcasting, DateTime ExpiryTime, string? GID);
|
public readonly record struct BroadcastEntry(bool IsBroadcasting, DateTime ExpiryTime, string? GID);
|
||||||
@@ -63,6 +64,9 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
_frameCounter++;
|
_frameCounter++;
|
||||||
var lookupsThisFrame = 0;
|
var lookupsThisFrame = 0;
|
||||||
|
|
||||||
@@ -104,7 +108,14 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
private async Task BatchUpdateBroadcastCacheAsync(List<string> cids)
|
private async Task BatchUpdateBroadcastCacheAsync(List<string> cids)
|
||||||
{
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
var results = await _broadcastService.AreUsersBroadcastingAsync(cids).ConfigureAwait(false);
|
var results = await _broadcastService.AreUsersBroadcastingAsync(cids).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
|
|
||||||
foreach (var (cid, info) in results)
|
foreach (var (cid, info) in results)
|
||||||
@@ -123,6 +134,9 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
|
|||||||
(_, old) => new BroadcastEntry(info.IsBroadcasting, expiry, info.GID));
|
(_, old) => new BroadcastEntry(info.IsBroadcasting, expiry, info.GID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
var activeCids = _broadcastCache
|
var activeCids = _broadcastCache
|
||||||
.Where(e => e.Value.IsBroadcasting && e.Value.ExpiryTime > now)
|
.Where(e => e.Value.IsBroadcasting && e.Value.ExpiryTime > now)
|
||||||
.Select(e => e.Key)
|
.Select(e => e.Key)
|
||||||
@@ -134,6 +148,9 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
private void OnBroadcastStatusChanged(BroadcastStatusChangedMessage msg)
|
private void OnBroadcastStatusChanged(BroadcastStatusChangedMessage msg)
|
||||||
{
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!msg.Enabled)
|
if (!msg.Enabled)
|
||||||
{
|
{
|
||||||
_broadcastCache.Clear();
|
_broadcastCache.Clear();
|
||||||
@@ -147,6 +164,9 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
private void UpdateSyncshellBroadcasts()
|
private void UpdateSyncshellBroadcasts()
|
||||||
{
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
var now = DateTime.UtcNow;
|
var now = DateTime.UtcNow;
|
||||||
var newSet = _broadcastCache
|
var newSet = _broadcastCache
|
||||||
.Where(e => e.Value.IsBroadcasting && e.Value.ExpiryTime > now && !string.IsNullOrEmpty(e.Value.GID))
|
.Where(e => e.Value.IsBroadcasting && e.Value.ExpiryTime > now && !string.IsNullOrEmpty(e.Value.GID))
|
||||||
@@ -230,17 +250,35 @@ public class LightFinderScannerService : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
|
_disposed = true;
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
_framework.Update -= OnFrameworkUpdate;
|
_framework.Update -= OnFrameworkUpdate;
|
||||||
if (_cleanupTask != null)
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_cleanupTask?.Wait(100, _cleanupCts.Token);
|
_cleanupCts.Cancel();
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
// Already disposed, can be ignored :)
|
||||||
}
|
}
|
||||||
|
|
||||||
_cleanupCts.Cancel();
|
try
|
||||||
_cleanupCts.Dispose();
|
{
|
||||||
|
_cleanupTask?.Wait(100);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Task may have already completed or been cancelled?
|
||||||
|
}
|
||||||
|
|
||||||
_cleanupTask?.Wait(100);
|
try
|
||||||
_cleanupCts.Dispose();
|
{
|
||||||
|
_cleanupCts.Dispose();
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
// Already disposed, ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user