From 4c268befdcae432f22686fdf35e6d2233408828f Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Thu, 6 Mar 2025 17:21:02 +0100 Subject: [PATCH] fix multiple PushCharacterData calls --- .../Pairs/VisibleUserDataDistributor.cs | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/MareSynchronos/PlayerData/Pairs/VisibleUserDataDistributor.cs b/MareSynchronos/PlayerData/Pairs/VisibleUserDataDistributor.cs index 7720960..4818f10 100644 --- a/MareSynchronos/PlayerData/Pairs/VisibleUserDataDistributor.cs +++ b/MareSynchronos/PlayerData/Pairs/VisibleUserDataDistributor.cs @@ -4,7 +4,6 @@ using MareSynchronos.Services.Mediator; using MareSynchronos.Utils; using MareSynchronos.WebAPI; using MareSynchronos.WebAPI.Files; -using MessagePack.Formatters; using Microsoft.Extensions.Logging; namespace MareSynchronos.PlayerData.Pairs; @@ -16,9 +15,13 @@ public class VisibleUserDataDistributor : DisposableMediatorSubscriberBase private readonly FileUploadManager _fileTransferManager; private readonly PairManager _pairManager; private CharacterData? _lastCreatedData; + private CharacterData? _uploadingCharacterData = null; private readonly List _previouslyVisiblePlayers = []; private Task? _fileUploadTask = null; private readonly HashSet _usersToPushDataTo = []; + private readonly SemaphoreSlim _pushDataSemaphore = new(1, 1); + private readonly CancellationTokenSource _runtimeCts = new(); + public VisibleUserDataDistributor(ILogger logger, ApiController apiController, DalamudUtilService dalamudUtil, PairManager pairManager, MareMediator mediator, FileUploadManager fileTransferManager) : base(logger, mediator) @@ -47,6 +50,17 @@ public class VisibleUserDataDistributor : DisposableMediatorSubscriberBase Mediator.Subscribe(this, (_) => _previouslyVisiblePlayers.Clear()); } + protected override void Dispose(bool disposing) + { + if (disposing) + { + _runtimeCts.Cancel(); + _runtimeCts.Dispose(); + } + + base.Dispose(disposing); + } + private void PushToAllVisibleUsers(bool forced = false) { foreach (var user in _pairManager.GetVisibleUsers()) @@ -80,16 +94,31 @@ public class VisibleUserDataDistributor : DisposableMediatorSubscriberBase _ = Task.Run(async () => { + forced |= _uploadingCharacterData?.DataHash != _lastCreatedData.DataHash; + if (_fileUploadTask == null || (_fileUploadTask?.IsCompleted ?? false) || forced) { - _fileUploadTask = _fileTransferManager.UploadFiles(_lastCreatedData.DeepClone(), [.. _usersToPushDataTo]); + _uploadingCharacterData = _lastCreatedData.DeepClone(); + Logger.LogDebug("Starting UploadTask for {hash}, Reason: TaskIsNull: {task}, TaskIsCompleted: {taskCpl}, Forced: {frc}", + _lastCreatedData.DataHash, _fileUploadTask == null, _fileUploadTask?.IsCompleted ?? false, false); + _fileUploadTask = _fileTransferManager.UploadFiles(_uploadingCharacterData, [.. _usersToPushDataTo]); } if (_fileUploadTask != null) { var dataToSend = await _fileUploadTask.ConfigureAwait(false); - await _apiController.PushCharacterData(dataToSend, [.. _usersToPushDataTo]).ConfigureAwait(false); - _usersToPushDataTo.Clear(); + await _pushDataSemaphore.WaitAsync(_runtimeCts.Token).ConfigureAwait(false); + try + { + if (!_usersToPushDataTo.Any()) return; + Logger.LogDebug("Pushing {data} to {users}", dataToSend.DataHash, string.Join(", ", _usersToPushDataTo.Select(k => k.AliasOrUID))); + await _apiController.PushCharacterData(dataToSend, [.. _usersToPushDataTo]).ConfigureAwait(false); + _usersToPushDataTo.Clear(); + } + finally + { + _pushDataSemaphore.Release(); + } } }); }