From 973ea83ab988a93426fe757105a8f543c5583b9b Mon Sep 17 00:00:00 2001 From: RaidMax Date: Mon, 24 Oct 2022 18:53:30 -0500 Subject: [PATCH] fix issue with random concurrency issue on interaction reaction --- Application/Misc/InteractionRegistration.cs | 37 ++++++++++++++------ WebfrontCore/Controllers/ActionController.cs | 11 ++++++ 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/Application/Misc/InteractionRegistration.cs b/Application/Misc/InteractionRegistration.cs index 31acf2fdc..99e173a0b 100644 --- a/Application/Misc/InteractionRegistration.cs +++ b/Application/Misc/InteractionRegistration.cs @@ -28,6 +28,13 @@ public class InteractionRegistration : IInteractionRegistration public void RegisterScriptInteraction(string interactionName, string source, Delegate interactionRegistration) { + if (string.IsNullOrWhiteSpace(source)) + { + throw new ArgumentException("Script interaction source cannot be null"); + } + + _logger.LogDebug("Registering script interaction {InteractionName} from {Source}", interactionName, source); + var plugin = _serviceProvider.GetRequiredService>() .FirstOrDefault(plugin => plugin.Name == source); @@ -36,17 +43,17 @@ public class InteractionRegistration : IInteractionRegistration return; } - var wrappedDelegate = (int? clientId, Reference.Game? game, CancellationToken token) => + Task WrappedDelegate(int? clientId, Reference.Game? game, CancellationToken token) => Task.FromResult( - scriptPlugin.WrapDelegate(interactionRegistration, clientId, game, token)); + scriptPlugin.WrapDelegate(interactionRegistration, token, clientId, game, token)); if (!_interactions.ContainsKey(interactionName)) { - _interactions.TryAdd(interactionName, wrappedDelegate); + _interactions.TryAdd(interactionName, WrappedDelegate); } else { - _interactions[interactionName] = wrappedDelegate; + _interactions[interactionName] = WrappedDelegate; } } @@ -54,27 +61,32 @@ public class InteractionRegistration : IInteractionRegistration { if (!_interactions.ContainsKey(interactionName)) { + _logger.LogDebug("Registering interaction {InteractionName}", interactionName); _interactions.TryAdd(interactionName, interactionRegistration); } else { + _logger.LogDebug("Updating interaction {InteractionName}", interactionName); _interactions[interactionName] = interactionRegistration; } } public void UnregisterInteraction(string interactionName) { - if (_interactions.ContainsKey(interactionName)) + if (!_interactions.ContainsKey(interactionName)) { - _interactions.TryRemove(interactionName, out _); + return; } + + _logger.LogDebug("Unregistering interaction {InteractionName}", interactionName); + _interactions.TryRemove(interactionName, out _); } public async Task> GetInteractions(string interactionPrefix = null, int? clientId = null, Reference.Game? game = null, CancellationToken token = default) { - return await GetInteractionsPrivate(interactionPrefix, clientId, game, token); + return await GetInteractionsInternal(interactionPrefix, clientId, game, token); } public async Task ProcessInteraction(string interactionId, int originId, int? targetId = null, @@ -103,7 +115,7 @@ public class InteractionRegistration : IInteractionRegistration continue; } - return scriptPlugin.ExecuteAction(interaction.ScriptAction, originId, targetId, game, meta, + return scriptPlugin.ExecuteAction(interaction.ScriptAction, token, originId, targetId, game, meta, token); } } @@ -118,10 +130,10 @@ public class InteractionRegistration : IInteractionRegistration return null; } - private async Task> GetInteractionsPrivate(string prefix = null, int? clientId = null, + private async Task> GetInteractionsInternal(string prefix = null, int? clientId = null, Reference.Game? game = null, CancellationToken token = default) { - return (await Task.WhenAll(_interactions + var interactions = _interactions .Where(interaction => string.IsNullOrWhiteSpace(prefix) || interaction.Key.StartsWith(prefix)).Select( async kvp => { @@ -137,6 +149,9 @@ public class InteractionRegistration : IInteractionRegistration clientId); return null; } - }))).Where(interaction => interaction is not null); + }).Where(interaction => interaction is not null) + .ToList(); + + return await Task.WhenAll(interactions); } } diff --git a/WebfrontCore/Controllers/ActionController.cs b/WebfrontCore/Controllers/ActionController.cs index 67bb890fa..057117d80 100644 --- a/WebfrontCore/Controllers/ActionController.cs +++ b/WebfrontCore/Controllers/ActionController.cs @@ -107,6 +107,17 @@ namespace WebfrontCore.Controllers } }); } + + if (meta is null) + { + return BadRequest(new[] + { + new CommandResponseInfo + { + Response = "INVALID" + } + }); + } var metaDict = JsonSerializer.Deserialize>(meta.TrimEnd('"').TrimStart('"'));