83 lines
3.0 KiB
C#
83 lines
3.0 KiB
C#
// -----------------------------------------------------------------------------
|
|
// IHybridLogicalClock.cs
|
|
// Sprint: SPRINT_20260105_002_001_LB_hlc_core_library
|
|
// Task: HLC-003 - Define HLC interface
|
|
// -----------------------------------------------------------------------------
|
|
|
|
namespace StellaOps.HybridLogicalClock;
|
|
|
|
/// <summary>
|
|
/// Hybrid Logical Clock for monotonic timestamp generation across distributed nodes.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// HLC combines physical (wall-clock) time with logical counters to provide:
|
|
/// - Monotonic timestamps even under clock skew
|
|
/// - Causal ordering guarantees across distributed nodes
|
|
/// - Deterministic tie-breaking for concurrent events
|
|
/// </remarks>
|
|
public interface IHybridLogicalClock
|
|
{
|
|
/// <summary>
|
|
/// Generate next timestamp for local event.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This should be called for every event that needs ordering:
|
|
/// - Job enqueue
|
|
/// - State transitions
|
|
/// - Audit log entries
|
|
/// </remarks>
|
|
/// <returns>New monotonically increasing HLC timestamp</returns>
|
|
HlcTimestamp Tick();
|
|
|
|
/// <summary>
|
|
/// Update clock on receiving remote timestamp, return merged result.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Called when receiving a message from another node to ensure
|
|
/// causal ordering is maintained across the distributed system.
|
|
/// </remarks>
|
|
/// <param name="remote">Timestamp from remote node</param>
|
|
/// <returns>New timestamp that is greater than both local clock and remote timestamp</returns>
|
|
/// <exception cref="HlcClockSkewException">If clock skew exceeds configured threshold</exception>
|
|
HlcTimestamp Receive(HlcTimestamp remote);
|
|
|
|
/// <summary>
|
|
/// Current clock state (for persistence/recovery).
|
|
/// </summary>
|
|
HlcTimestamp Current { get; }
|
|
|
|
/// <summary>
|
|
/// Node identifier for this clock instance.
|
|
/// </summary>
|
|
string NodeId { get; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Persistent storage for HLC state (survives restarts).
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Implementations should ensure atomic updates to prevent state loss
|
|
/// during concurrent access or node failures.
|
|
/// </remarks>
|
|
public interface IHlcStateStore
|
|
{
|
|
/// <summary>
|
|
/// Load last persisted HLC state for node.
|
|
/// </summary>
|
|
/// <param name="nodeId">Node identifier to load state for</param>
|
|
/// <param name="ct">Cancellation token</param>
|
|
/// <returns>Last persisted timestamp, or null if no state exists</returns>
|
|
Task<HlcTimestamp?> LoadAsync(string nodeId, CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Persist HLC state.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Called after each tick to ensure state survives restarts.
|
|
/// Implementations may batch or debounce writes for performance.
|
|
/// </remarks>
|
|
/// <param name="timestamp">Current timestamp to persist</param>
|
|
/// <param name="ct">Cancellation token</param>
|
|
Task SaveAsync(HlcTimestamp timestamp, CancellationToken ct = default);
|
|
}
|