using System.Threading.Channels; using Jiaowu.Api.Domain.System; namespace Jiaowu.Api.Infrastructure.BackgroundJobs; public sealed record BackgroundJobEnvelope( Guid OutboxMessageId, BackgroundJobKind JobKind, Guid JobId); public interface IBackgroundJobTransport { bool IsDurable { get; } ValueTask PublishAsync( BackgroundJobEnvelope message, CancellationToken cancellationToken); Task CheckHealthAsync(CancellationToken cancellationToken); } public sealed class InMemoryBackgroundJobTransport : IBackgroundJobTransport { private readonly IReadOnlyDictionary< BackgroundJobKind, Channel> _channels = Enum.GetValues().ToDictionary( kind => kind, _ => Channel.CreateBounded( new BoundedChannelOptions(256) { FullMode = BoundedChannelFullMode.Wait, SingleReader = false, SingleWriter = false })); public bool IsDurable => false; public ValueTask PublishAsync( BackgroundJobEnvelope message, CancellationToken cancellationToken) => _channels[message.JobKind].Writer.WriteAsync(message, cancellationToken); public Task CheckHealthAsync(CancellationToken cancellationToken) => Task.FromResult(true); public IAsyncEnumerable ReadAllAsync( BackgroundJobKind kind, CancellationToken cancellationToken) => _channels[kind].Reader.ReadAllAsync(cancellationToken); }