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