Fixes issue where api calls are missed due to initialized components

This commit is contained in:
Ben 2025-04-17 14:55:32 +02:00
parent b118f7d103
commit 2b7b8161b3
No known key found for this signature in database
GPG Key ID: 0F16E812E736C24B
5 changed files with 98 additions and 32 deletions

View File

@ -0,0 +1,66 @@
using Logging;
namespace BiblioTech
{
public class CallDispatcher
{
private readonly ILog log;
private readonly object _lock = new object();
private readonly List<Action> queue = new List<Action>();
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<Action>();
lock (_lock)
{
tasks = queue.ToArray();
queue.Clear();
}
foreach (var task in tasks)
{
task();
}
}
}
}

View File

@ -84,6 +84,7 @@ namespace BiblioTech
log.Error(json);
throw;
}
Program.Dispatcher.Start();
log.Log("Initialized.");
}

View File

@ -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<Configuration>(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...");

View File

@ -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);
}

View File

@ -39,23 +39,18 @@ namespace BiblioTech.Rewards
[HttpPost]
public async Task<string> 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<Task> action)
{
try
{
await action();
}
catch (Exception ex)
{
Program.Log.Error("Exception: " + ex);
}
}
}
}