Files
satellite-provider/SatelliteProvider.Services/RegionRequestQueue.cs
T
2025-11-19 13:01:30 +01:00

59 lines
2.0 KiB
C#

using System.Threading.Channels;
using Microsoft.Extensions.Logging;
using SatelliteProvider.Common.DTO;
using SatelliteProvider.Common.Interfaces;
namespace SatelliteProvider.Services;
public class RegionRequestQueue : IRegionRequestQueue
{
private readonly Channel<RegionRequest> _queue;
private readonly ILogger<RegionRequestQueue>? _logger;
private int _totalEnqueued = 0;
private int _totalDequeued = 0;
public RegionRequestQueue(int capacity, ILogger<RegionRequestQueue>? logger = null)
{
var options = new BoundedChannelOptions(capacity)
{
FullMode = BoundedChannelFullMode.Wait
};
_queue = Channel.CreateBounded<RegionRequest>(options);
_logger = logger;
_logger?.LogInformation("RegionRequestQueue created with capacity {Capacity}", capacity);
}
public async ValueTask EnqueueAsync(RegionRequest request, CancellationToken cancellationToken = default)
{
var queueDepthBefore = Count;
_totalEnqueued++;
_logger?.LogDebug("Enqueuing region {RegionId} (queue depth before: {Depth}, total enqueued: {Total})",
request.Id, queueDepthBefore, _totalEnqueued);
await _queue.Writer.WriteAsync(request, cancellationToken);
var queueDepthAfter = Count;
_logger?.LogDebug("Enqueued region {RegionId} (queue depth after: {Depth})",
request.Id, queueDepthAfter);
}
public async ValueTask<RegionRequest?> DequeueAsync(CancellationToken cancellationToken = default)
{
if (await _queue.Reader.WaitToReadAsync(cancellationToken))
{
if (_queue.Reader.TryRead(out var request))
{
_totalDequeued++;
var queueDepth = Count;
_logger?.LogDebug("Dequeued region {RegionId} (queue depth: {Depth}, total dequeued: {Total})",
request.Id, queueDepth, _totalDequeued);
return request;
}
}
return null;
}
public int Count => _queue.Reader.Count;
}