Skip to content

Effects Composition

The ClockModule is an [EffectsModule(typeof(IClock))] that generates an Eff<RT, T> effect method for getting the current time. This enables deterministic time in effect pipelines and tests.

Capability Interface

public interface IHasClock
{
    IClock Clock { get; }
}

Effect Method

public static partial class ClockModule
{
    public static partial class Clock
    {
        public static Eff<RT, DateTimeOffset> GetUtcNow<RT>()
            where RT : IHasClock => ...
    }
}

Why Use Clock Effects?

Direct DateTimeOffset.UtcNow calls are non-deterministic and untestable. The clock effect lets you:

  1. Test time-dependent logic — inject a fixed time in tests
  2. Compose with other effects — time reads participate in the effect pipeline
  3. Get OpenTelemetry tracing — clock reads appear in traces

Effect Pipeline Examples

Time-stamped operations

var createOrder =
    from now in ClockModule.Clock.GetUtcNow<AppRuntime>()
    from order in AppStore.Orders.Save<AppRuntime>(new Order
    {
        Id = OrderId.New(),
        CreatedAt = now,
        Status = OrderStatus.Pending
    })
    select order;

Expiry checks

var checkExpiry =
    from now in ClockModule.Clock.GetUtcNow<AppRuntime>()
    from token in AppStore.Tokens.GetById<AppRuntime>(tokenId)
        .Require(Error.New(404, "Token not found"))
    from _ in Guard<AppRuntime>(token.ExpiresAt > now,
        Error.New(401, "Token expired"))
    select token;

Testing

Swap the clock in tests for deterministic behavior:

var fixedTime = new DateTimeOffset(2026, 3, 15, 12, 0, 0, TimeSpan.Zero);
var runtime = TestAppRuntime.Create()
    .WithClock(new TestClock(fixedTime));