Split MAX bot loops and make chats cache-first
This commit is contained in:
@@ -21,8 +21,12 @@ public sealed class MaxOutboxService(
|
||||
|
||||
public async Task<int> ProcessOnceAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var processed = 0;
|
||||
var processed = await ProcessPendingMessagesOnceAsync(cancellationToken);
|
||||
return processed + await ProcessPendingChatActionsOnceAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<int> ProcessPendingMessagesOnceAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var candidates = await db.Messages
|
||||
.Include(message => message.Chat)
|
||||
.Include(message => message.Attachments)
|
||||
@@ -41,6 +45,7 @@ public sealed class MaxOutboxService(
|
||||
.Take(10)
|
||||
.ToArray();
|
||||
|
||||
var processed = 0;
|
||||
foreach (var message in pending)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -50,10 +55,10 @@ public sealed class MaxOutboxService(
|
||||
}
|
||||
}
|
||||
|
||||
return processed + await ProcessPendingChatActionsAsync(cancellationToken);
|
||||
return processed;
|
||||
}
|
||||
|
||||
private async Task<int> ProcessPendingChatActionsAsync(CancellationToken cancellationToken)
|
||||
public async Task<int> ProcessPendingChatActionsOnceAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
var pending = await db.Chats
|
||||
|
||||
@@ -13,6 +13,26 @@ public sealed class MaxOutboxWorker(
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
var delay = TimeSpan.FromSeconds(Math.Max(1, _options.MaxOutboxPollIntervalSeconds));
|
||||
|
||||
await Task.WhenAll(
|
||||
RunOutboxLoopAsync(
|
||||
"message outbox",
|
||||
delay,
|
||||
(outbox, cancellationToken) => outbox.ProcessPendingMessagesOnceAsync(cancellationToken),
|
||||
stoppingToken),
|
||||
RunOutboxLoopAsync(
|
||||
"chat command outbox",
|
||||
delay,
|
||||
(outbox, cancellationToken) => outbox.ProcessPendingChatActionsOnceAsync(cancellationToken),
|
||||
stoppingToken));
|
||||
}
|
||||
|
||||
private async Task RunOutboxLoopAsync(
|
||||
string workerName,
|
||||
TimeSpan delay,
|
||||
Func<MaxOutboxService, CancellationToken, Task<int>> process,
|
||||
CancellationToken stoppingToken)
|
||||
{
|
||||
using var timer = new PeriodicTimer(delay);
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
@@ -30,11 +50,11 @@ public sealed class MaxOutboxWorker(
|
||||
{
|
||||
await using var scope = scopeFactory.CreateAsyncScope();
|
||||
var outbox = scope.ServiceProvider.GetRequiredService<MaxOutboxService>();
|
||||
await outbox.ProcessOnceAsync(stoppingToken);
|
||||
await process(outbox, stoppingToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogWarning(ex, "QMAX outbox tick failed.");
|
||||
logger.LogWarning(ex, "QMAX {WorkerName} tick failed.", workerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user