using System.Collections.Concurrent; using System.Threading.Channels; namespace RazorPagesMovie.Services; public interface IContactMessageNotificationQueue { void Enqueue(Guid contactMessageId); IAsyncEnumerable DequeueAllAsync(CancellationToken cancellationToken); void Release(Guid contactMessageId); } public class ContactMessageNotificationQueue : IContactMessageNotificationQueue { private readonly Channel _channel = Channel.CreateUnbounded(); private readonly ConcurrentDictionary _inFlight = new(); public void Enqueue(Guid contactMessageId) { if (_inFlight.TryAdd(contactMessageId, 0)) { _channel.Writer.TryWrite(contactMessageId); } } public IAsyncEnumerable DequeueAllAsync(CancellationToken cancellationToken) => _channel.Reader.ReadAllAsync(cancellationToken); public void Release(Guid contactMessageId) => _inFlight.TryRemove(contactMessageId, out _); }