forked from gongxuegit/tiku-backend.net
perf: optimize authorization scoreline and workers
This commit is contained in:
66
Tiku.Api/Observability/OutboxBacklogMonitor.cs
Normal file
66
Tiku.Api/Observability/OutboxBacklogMonitor.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System.Diagnostics.Metrics;
|
||||
using Npgsql;
|
||||
using Tiku.Infrastructure.Messaging;
|
||||
|
||||
namespace Tiku.Api.Observability;
|
||||
|
||||
public sealed class OutboxBacklogSnapshot
|
||||
{
|
||||
private static readonly Meter Meter = new("Tiku.Messaging", "1.0.0");
|
||||
private long pending;
|
||||
private double oldestAgeSeconds;
|
||||
|
||||
public OutboxBacklogSnapshot()
|
||||
{
|
||||
Meter.CreateObservableGauge("tiku.outbox.pending", () => Interlocked.Read(ref pending));
|
||||
Meter.CreateObservableGauge("tiku.outbox.oldest_age", () => Volatile.Read(ref oldestAgeSeconds), "s");
|
||||
}
|
||||
|
||||
internal long Pending => Interlocked.Read(ref pending);
|
||||
internal double OldestAgeSeconds => Volatile.Read(ref oldestAgeSeconds);
|
||||
|
||||
internal void Update(long count, DateTime? oldestSentTime)
|
||||
{
|
||||
Interlocked.Exchange(ref pending, count);
|
||||
Volatile.Write(ref oldestAgeSeconds, oldestSentTime is null
|
||||
? 0
|
||||
: Math.Max(0, (DateTimeOffset.UtcNow - new DateTimeOffset(oldestSentTime.Value)).TotalSeconds));
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class OutboxBacklogMonitor(
|
||||
NpgsqlDataSource dataSource,
|
||||
OutboxBacklogSnapshot snapshot,
|
||||
MessagingOptions messagingOptions,
|
||||
ILogger<OutboxBacklogMonitor> logger) : BackgroundService
|
||||
{
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (messagingOptions.IsConfigured)
|
||||
{
|
||||
await using var command = dataSource.CreateCommand(
|
||||
"SELECT count(*), min(sent_time) FROM outbox_message;");
|
||||
await using var reader = await command.ExecuteReaderAsync(stoppingToken);
|
||||
if (await reader.ReadAsync(stoppingToken))
|
||||
{
|
||||
snapshot.Update(reader.GetInt64(0), reader.IsDBNull(1) ? null : reader.GetDateTime(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
logger.LogWarning(exception, "Outbox backlog metric collection failed.");
|
||||
}
|
||||
|
||||
await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user