using System; using System.Collections.Generic; namespace StellaOps.Scanner.Queue; public sealed class ScanQueueMessage { private readonly byte[] _payload; public ScanQueueMessage(string jobId, ReadOnlyMemory payload) { if (string.IsNullOrWhiteSpace(jobId)) { throw new ArgumentException("Job identifier must be provided.", nameof(jobId)); } JobId = jobId; _payload = CopyPayload(payload); } public string JobId { get; } public string? IdempotencyKey { get; init; } public string? TraceId { get; init; } public IReadOnlyDictionary? Attributes { get; init; } public ReadOnlyMemory Payload => _payload; private static byte[] CopyPayload(ReadOnlyMemory payload) { if (payload.Length == 0) { return Array.Empty(); } var copy = new byte[payload.Length]; payload.Span.CopyTo(copy); return copy; } } public readonly record struct QueueEnqueueResult(string MessageId, bool Deduplicated); public sealed class QueueLeaseRequest { public QueueLeaseRequest(string consumer, int batchSize, TimeSpan leaseDuration) { if (string.IsNullOrWhiteSpace(consumer)) { throw new ArgumentException("Consumer name must be provided.", nameof(consumer)); } if (batchSize <= 0) { throw new ArgumentOutOfRangeException(nameof(batchSize), batchSize, "Batch size must be positive."); } if (leaseDuration <= TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(leaseDuration), leaseDuration, "Lease duration must be positive."); } Consumer = consumer; BatchSize = batchSize; LeaseDuration = leaseDuration; } public string Consumer { get; } public int BatchSize { get; } public TimeSpan LeaseDuration { get; } } public sealed class QueueClaimOptions { public QueueClaimOptions( string claimantConsumer, int batchSize, TimeSpan minIdleTime) { if (string.IsNullOrWhiteSpace(claimantConsumer)) { throw new ArgumentException("Consumer must be provided.", nameof(claimantConsumer)); } if (batchSize <= 0) { throw new ArgumentOutOfRangeException(nameof(batchSize), batchSize, "Batch size must be positive."); } if (minIdleTime < TimeSpan.Zero) { throw new ArgumentOutOfRangeException(nameof(minIdleTime), minIdleTime, "Idle time cannot be negative."); } ClaimantConsumer = claimantConsumer; BatchSize = batchSize; MinIdleTime = minIdleTime; } public string ClaimantConsumer { get; } public int BatchSize { get; } public TimeSpan MinIdleTime { get; } } public enum QueueReleaseDisposition { Retry, Abandon }