146 lines
4.7 KiB
C#
146 lines
4.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Svrnty.CQRS.Events.Abstractions.Projections;
|
|
|
|
/// <summary>
|
|
/// Registry for managing projection definitions and their configurations.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// <strong>Phase 7 Feature - Projection Registry:</strong>
|
|
/// The registry maintains metadata about all registered projections,
|
|
/// including which streams they consume and how they should be executed.
|
|
/// </para>
|
|
/// </remarks>
|
|
public interface IProjectionRegistry
|
|
{
|
|
/// <summary>
|
|
/// Registers a projection with the registry.
|
|
/// </summary>
|
|
/// <param name="definition">The projection definition.</param>
|
|
void Register(ProjectionDefinition definition);
|
|
|
|
/// <summary>
|
|
/// Gets a projection definition by name.
|
|
/// </summary>
|
|
/// <param name="projectionName">The unique name of the projection.</param>
|
|
/// <returns>The projection definition, or null if not found.</returns>
|
|
ProjectionDefinition? GetProjection(string projectionName);
|
|
|
|
/// <summary>
|
|
/// Gets all registered projection definitions.
|
|
/// </summary>
|
|
/// <returns>All projection definitions.</returns>
|
|
IEnumerable<ProjectionDefinition> GetAllProjections();
|
|
|
|
/// <summary>
|
|
/// Gets all projections that consume from a specific stream.
|
|
/// </summary>
|
|
/// <param name="streamName">The name of the stream.</param>
|
|
/// <returns>All projection definitions consuming from this stream.</returns>
|
|
IEnumerable<ProjectionDefinition> GetProjectionsForStream(string streamName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Defines a projection's configuration and behavior.
|
|
/// </summary>
|
|
public sealed record ProjectionDefinition
|
|
{
|
|
/// <summary>
|
|
/// The unique name of the projection.
|
|
/// </summary>
|
|
public required string ProjectionName { get; init; }
|
|
|
|
/// <summary>
|
|
/// The name of the stream to consume from.
|
|
/// </summary>
|
|
public required string StreamName { get; init; }
|
|
|
|
/// <summary>
|
|
/// The type of the projection implementation.
|
|
/// </summary>
|
|
public required Type ProjectionType { get; init; }
|
|
|
|
/// <summary>
|
|
/// The type of events this projection handles.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Null if projection implements IDynamicProjection and handles multiple event types.
|
|
/// </remarks>
|
|
public Type? EventType { get; init; }
|
|
|
|
/// <summary>
|
|
/// Execution options for the projection.
|
|
/// </summary>
|
|
public ProjectionOptions Options { get; init; } = new();
|
|
|
|
/// <summary>
|
|
/// Optional description of what this projection does.
|
|
/// </summary>
|
|
public string? Description { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configuration options for projection execution.
|
|
/// </summary>
|
|
public sealed record ProjectionOptions
|
|
{
|
|
/// <summary>
|
|
/// Number of events to read from stream per batch.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Default: 100. Larger batches = higher throughput but more memory.
|
|
/// </remarks>
|
|
public int BatchSize { get; set; } = 100;
|
|
|
|
/// <summary>
|
|
/// Whether to start the projection automatically on application startup.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Default: true. Set to false for projections that should be started manually.
|
|
/// </remarks>
|
|
public bool AutoStart { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// Maximum number of retry attempts for failed events.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Default: 3. After max retries, the projection moves to Failed state.
|
|
/// </remarks>
|
|
public int MaxRetries { get; set; } = 3;
|
|
|
|
/// <summary>
|
|
/// Base delay for exponential backoff retry strategy.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Default: 1 second. Actual delay = BaseRetryDelay * 2^(attemptNumber).
|
|
/// </remarks>
|
|
public TimeSpan BaseRetryDelay { get; set; } = TimeSpan.FromSeconds(1);
|
|
|
|
/// <summary>
|
|
/// How often to poll for new events when caught up.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Default: 1 second. Shorter = more responsive, longer = less database load.
|
|
/// </remarks>
|
|
public TimeSpan PollingInterval { get; set; } = TimeSpan.FromSeconds(1);
|
|
|
|
/// <summary>
|
|
/// Whether to checkpoint after each event or only after each batch.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Default: false (checkpoint per batch). Set to true for exactly-once semantics
|
|
/// at the cost of higher checkpoint overhead.
|
|
/// </remarks>
|
|
public bool CheckpointPerEvent { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// Whether this projection can be reset and rebuilt.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Default: true. Set to false to prevent accidental rebuilds of critical projections.
|
|
/// </remarks>
|
|
public bool AllowRebuild { get; set; } = true;
|
|
}
|