diff --git a/Tools/BiblioTech/CallDispatcher.cs b/Tools/BiblioTech/CallDispatcher.cs new file mode 100644 index 00000000..b24ea830 --- /dev/null +++ b/Tools/BiblioTech/CallDispatcher.cs @@ -0,0 +1,66 @@ +using Logging; + +namespace BiblioTech +{ + public class CallDispatcher + { + private readonly ILog log; + private readonly object _lock = new object(); + private readonly List queue = new List(); + private readonly AutoResetEvent autoResetEvent = new AutoResetEvent(false); + + public CallDispatcher(ILog log) + { + this.log = log; + } + + public void Add(Action call) + { + lock (_lock) + { + queue.Add(call); + autoResetEvent.Set(); + if (queue.Count > 100) + { + log.Error("Queue overflow!"); + queue.Clear(); + } + } + } + + public void Start() + { + Task.Run(() => + { + while (true) + { + try + { + Worker(); + } + catch (Exception ex) + { + log.Error("Exception in CallDispatcher: " + ex); + } + } + }); + } + + private void Worker() + { + autoResetEvent.WaitOne(); + var tasks = Array.Empty(); + + lock (_lock) + { + tasks = queue.ToArray(); + queue.Clear(); + } + + foreach (var task in tasks) + { + task(); + } + } + } +} diff --git a/Tools/BiblioTech/CommandHandler.cs b/Tools/BiblioTech/CommandHandler.cs index 822d4446..10e1e24b 100644 --- a/Tools/BiblioTech/CommandHandler.cs +++ b/Tools/BiblioTech/CommandHandler.cs @@ -84,6 +84,7 @@ namespace BiblioTech log.Error(json); throw; } + Program.Dispatcher.Start(); log.Log("Initialized."); } diff --git a/Tools/BiblioTech/Program.cs b/Tools/BiblioTech/Program.cs index 2e0427e6..0ce84bde 100644 --- a/Tools/BiblioTech/Program.cs +++ b/Tools/BiblioTech/Program.cs @@ -16,6 +16,7 @@ namespace BiblioTech private DiscordSocketClient client = null!; private CustomReplacement replacement = null!; + public static CallDispatcher Dispatcher { get; private set; } = null!; public static Configuration Config { get; private set; } = null!; public static UserRepo UserRepo { get; } = new UserRepo(); public static AdminChecker AdminChecker { get; private set; } = null!; @@ -26,8 +27,6 @@ namespace BiblioTech public static Task Main(string[] args) { - Log = new ConsoleLog(); - var uniformArgs = new ArgsUniform(PrintHelp, args); Config = uniformArgs.Parse(); @@ -36,6 +35,8 @@ namespace BiblioTech new ConsoleLog() ); + Dispatcher = new CallDispatcher(Log); + EnsurePath(Config.DataPath); EnsurePath(Config.UserDataPath); EnsurePath(Config.EndpointsPath); @@ -44,18 +45,6 @@ namespace BiblioTech return new Program().MainAsync(args); } - public static void Write(EventsAndErrors cmd) - { - if (Log == null) return; - - if (cmd == null) - { - Log.Log("cmd is null!"); - return; - } - Log.Log(JsonConvert.SerializeObject(cmd)); - } - public async Task MainAsync(string[] args) { Log.Log("Starting Codex Discord Bot..."); diff --git a/Tools/BiblioTech/Rewards/ChainActivityHandler.cs b/Tools/BiblioTech/Rewards/ChainActivityHandler.cs index 66fe5e63..64f08e38 100644 --- a/Tools/BiblioTech/Rewards/ChainActivityHandler.cs +++ b/Tools/BiblioTech/Rewards/ChainActivityHandler.cs @@ -18,10 +18,25 @@ namespace BiblioTech.Rewards public async Task ProcessChainActivity(ActiveChainAddresses activeChainAddresses) { - if (!activeChainAddresses.HasAny()) return; + if (!activeChainAddresses.HasAny()) + { + Log("Received empty activeChainAddresses."); + return; + } + var activeUserIds = ConvertToUserIds(activeChainAddresses); - if (!activeUserIds.HasAny()) return; - if (!HasChanged(activeUserIds)) return; + if (!activeUserIds.HasAny()) + { + Log("Empty userIds after lookup of addresses: " + activeChainAddresses); + return; + } + + if (!HasChanged(activeUserIds)) + { + Log("Active userIds has not changed: " + activeUserIds); + return; + } + await GiveAndRemoveRoles(activeUserIds); } diff --git a/Tools/BiblioTech/Rewards/RewardController.cs b/Tools/BiblioTech/Rewards/RewardController.cs index 1879c6e7..43a01ad5 100644 --- a/Tools/BiblioTech/Rewards/RewardController.cs +++ b/Tools/BiblioTech/Rewards/RewardController.cs @@ -39,23 +39,18 @@ namespace BiblioTech.Rewards [HttpPost] public async Task Give(EventsAndErrors cmd) { - Program.Write(cmd); + Program.Dispatcher.Add(() => + { + Program.ChainActivityHandler.ProcessChainActivity(cmd.ActiveChainAddresses).Wait(); + }); - await Safe(() => Program.ChainActivityHandler.ProcessChainActivity(cmd.ActiveChainAddresses)); - await Safe(() => Program.EventsSender.ProcessChainEvents(cmd.EventsOverview, cmd.Errors)); + Program.Dispatcher.Add(() => + { + Program.EventsSender.ProcessChainEvents(cmd.EventsOverview, cmd.Errors).Wait(); + }); + + await Task.CompletedTask; return "OK"; } - - private async Task Safe(Func action) - { - try - { - await action(); - } - catch (Exception ex) - { - Program.Log.Error("Exception: " + ex); - } - } } }