fix issue with random concurrency issue on interaction reaction

This commit is contained in:
RaidMax 2022-10-24 18:53:30 -05:00
parent 69cb4bf9df
commit 973ea83ab9
2 changed files with 37 additions and 11 deletions

View File

@ -28,6 +28,13 @@ public class InteractionRegistration : IInteractionRegistration
public void RegisterScriptInteraction(string interactionName, string source, Delegate interactionRegistration) 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<IEnumerable<IPlugin>>() var plugin = _serviceProvider.GetRequiredService<IEnumerable<IPlugin>>()
.FirstOrDefault(plugin => plugin.Name == source); .FirstOrDefault(plugin => plugin.Name == source);
@ -36,17 +43,17 @@ public class InteractionRegistration : IInteractionRegistration
return; return;
} }
var wrappedDelegate = (int? clientId, Reference.Game? game, CancellationToken token) => Task<IInteractionData> WrappedDelegate(int? clientId, Reference.Game? game, CancellationToken token) =>
Task.FromResult( Task.FromResult(
scriptPlugin.WrapDelegate<IInteractionData>(interactionRegistration, clientId, game, token)); scriptPlugin.WrapDelegate<IInteractionData>(interactionRegistration, token, clientId, game, token));
if (!_interactions.ContainsKey(interactionName)) if (!_interactions.ContainsKey(interactionName))
{ {
_interactions.TryAdd(interactionName, wrappedDelegate); _interactions.TryAdd(interactionName, WrappedDelegate);
} }
else else
{ {
_interactions[interactionName] = wrappedDelegate; _interactions[interactionName] = WrappedDelegate;
} }
} }
@ -54,27 +61,32 @@ public class InteractionRegistration : IInteractionRegistration
{ {
if (!_interactions.ContainsKey(interactionName)) if (!_interactions.ContainsKey(interactionName))
{ {
_logger.LogDebug("Registering interaction {InteractionName}", interactionName);
_interactions.TryAdd(interactionName, interactionRegistration); _interactions.TryAdd(interactionName, interactionRegistration);
} }
else else
{ {
_logger.LogDebug("Updating interaction {InteractionName}", interactionName);
_interactions[interactionName] = interactionRegistration; _interactions[interactionName] = interactionRegistration;
} }
} }
public void UnregisterInteraction(string interactionName) 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<IEnumerable<IInteractionData>> GetInteractions(string interactionPrefix = null, public async Task<IEnumerable<IInteractionData>> GetInteractions(string interactionPrefix = null,
int? clientId = null, int? clientId = null,
Reference.Game? game = null, CancellationToken token = default) Reference.Game? game = null, CancellationToken token = default)
{ {
return await GetInteractionsPrivate(interactionPrefix, clientId, game, token); return await GetInteractionsInternal(interactionPrefix, clientId, game, token);
} }
public async Task<string> ProcessInteraction(string interactionId, int originId, int? targetId = null, public async Task<string> ProcessInteraction(string interactionId, int originId, int? targetId = null,
@ -103,7 +115,7 @@ public class InteractionRegistration : IInteractionRegistration
continue; continue;
} }
return scriptPlugin.ExecuteAction<string>(interaction.ScriptAction, originId, targetId, game, meta, return scriptPlugin.ExecuteAction<string>(interaction.ScriptAction, token, originId, targetId, game, meta,
token); token);
} }
} }
@ -118,10 +130,10 @@ public class InteractionRegistration : IInteractionRegistration
return null; return null;
} }
private async Task<IEnumerable<IInteractionData>> GetInteractionsPrivate(string prefix = null, int? clientId = null, private async Task<IEnumerable<IInteractionData>> GetInteractionsInternal(string prefix = null, int? clientId = null,
Reference.Game? game = null, CancellationToken token = default) 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( .Where(interaction => string.IsNullOrWhiteSpace(prefix) || interaction.Key.StartsWith(prefix)).Select(
async kvp => async kvp =>
{ {
@ -137,6 +149,9 @@ public class InteractionRegistration : IInteractionRegistration
clientId); clientId);
return null; return null;
} }
}))).Where(interaction => interaction is not null); }).Where(interaction => interaction is not null)
.ToList();
return await Task.WhenAll(interactions);
} }
} }

View File

@ -108,6 +108,17 @@ namespace WebfrontCore.Controllers
}); });
} }
if (meta is null)
{
return BadRequest(new[]
{
new CommandResponseInfo
{
Response = "INVALID"
}
});
}
var metaDict = JsonSerializer.Deserialize<Dictionary<string, string>>(meta.TrimEnd('"').TrimStart('"')); var metaDict = JsonSerializer.Deserialize<Dictionary<string, string>>(meta.TrimEnd('"').TrimStart('"'));
if (metaDict is null) if (metaDict is null)