121 lines
3.5 KiB
C#
121 lines
3.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Svrnty.CQRS.Events.Abstractions.Sagas;
|
|
|
|
/// <summary>
|
|
/// Persistent storage for saga state.
|
|
/// </summary>
|
|
public interface ISagaStateStore
|
|
{
|
|
/// <summary>
|
|
/// Save saga state.
|
|
/// </summary>
|
|
/// <param name="state">The saga state to save.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
Task SaveStateAsync(SagaStateSnapshot state, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Load saga state.
|
|
/// </summary>
|
|
/// <param name="sagaId">The saga ID.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>The saga state, or null if not found.</returns>
|
|
Task<SagaStateSnapshot?> LoadStateAsync(string sagaId, CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Get all sagas for a correlation ID.
|
|
/// </summary>
|
|
/// <param name="correlationId">The correlation ID.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>List of saga states.</returns>
|
|
Task<List<SagaStateSnapshot>> GetByCorrelationIdAsync(
|
|
string correlationId,
|
|
CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Get sagas by state.
|
|
/// </summary>
|
|
/// <param name="state">The saga state to filter by.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
/// <returns>List of saga states.</returns>
|
|
Task<List<SagaStateSnapshot>> GetByStateAsync(
|
|
SagaState state,
|
|
CancellationToken cancellationToken = default);
|
|
|
|
/// <summary>
|
|
/// Delete saga state.
|
|
/// </summary>
|
|
/// <param name="sagaId">The saga ID to delete.</param>
|
|
/// <param name="cancellationToken">Cancellation token.</param>
|
|
Task DeleteStateAsync(string sagaId, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Snapshot of saga state for persistence.
|
|
/// </summary>
|
|
public sealed record SagaStateSnapshot
|
|
{
|
|
/// <summary>
|
|
/// Saga instance ID.
|
|
/// </summary>
|
|
public required string SagaId { get; init; }
|
|
|
|
/// <summary>
|
|
/// Correlation ID.
|
|
/// </summary>
|
|
public required string CorrelationId { get; init; }
|
|
|
|
/// <summary>
|
|
/// Saga type name.
|
|
/// </summary>
|
|
public required string SagaName { get; init; }
|
|
|
|
/// <summary>
|
|
/// Current state.
|
|
/// </summary>
|
|
public SagaState State { get; init; }
|
|
|
|
/// <summary>
|
|
/// Current step index.
|
|
/// </summary>
|
|
public int CurrentStep { get; init; }
|
|
|
|
/// <summary>
|
|
/// Total number of steps.
|
|
/// </summary>
|
|
public int TotalSteps { get; init; }
|
|
|
|
/// <summary>
|
|
/// Completed steps (for compensation tracking).
|
|
/// </summary>
|
|
public List<string> CompletedSteps { get; init; } = new();
|
|
|
|
/// <summary>
|
|
/// When the saga started.
|
|
/// </summary>
|
|
public DateTimeOffset StartedAt { get; init; }
|
|
|
|
/// <summary>
|
|
/// When the saga was last updated.
|
|
/// </summary>
|
|
public DateTimeOffset LastUpdated { get; init; }
|
|
|
|
/// <summary>
|
|
/// When the saga completed (if completed).
|
|
/// </summary>
|
|
public DateTimeOffset? CompletedAt { get; init; }
|
|
|
|
/// <summary>
|
|
/// Error message (if failed).
|
|
/// </summary>
|
|
public string? ErrorMessage { get; init; }
|
|
|
|
/// <summary>
|
|
/// Saga data (serialized as JSON or similar).
|
|
/// </summary>
|
|
public Dictionary<string, object> Data { get; init; } = new();
|
|
}
|