using System; using Svrnty.CQRS.Events.Abstractions.Storage; using System.Threading; using System.Threading.Tasks; namespace Svrnty.CQRS.Events.Abstractions.Storage; /// /// Store for tracking processed events to prevent duplicate processing (exactly-once delivery semantics). /// public interface IIdempotencyStore { /// /// Check if an event has already been processed by a specific consumer. /// /// Unique identifier for the consumer /// Unique identifier for the event /// Cancellation token /// True if the event was already processed, false otherwise Task WasProcessedAsync( string consumerId, string eventId, CancellationToken cancellationToken = default); /// /// Mark an event as processed by a specific consumer. /// /// Unique identifier for the consumer /// Unique identifier for the event /// Timestamp when the event was processed /// Cancellation token Task MarkProcessedAsync( string consumerId, string eventId, DateTimeOffset processedAt, CancellationToken cancellationToken = default); /// /// Try to acquire an idempotency lock to prevent concurrent processing of the same event. /// /// Unique key for the operation (typically consumerId:eventId) /// How long the lock should be held /// Cancellation token /// True if the lock was acquired, false if another process holds the lock Task TryAcquireIdempotencyLockAsync( string idempotencyKey, TimeSpan lockDuration, CancellationToken cancellationToken = default); /// /// Release an acquired idempotency lock. /// /// Unique key for the operation /// Cancellation token Task ReleaseIdempotencyLockAsync( string idempotencyKey, CancellationToken cancellationToken = default); /// /// Clean up old processed event records to prevent unbounded growth. /// /// Remove records processed before this timestamp /// Cancellation token /// Number of records removed Task CleanupAsync( DateTimeOffset olderThan, CancellationToken cancellationToken = default); }