Skip to content

Effects Composition

The Event Queue generator emits effect methods on the queue's static partial class, enabling type-safe composition with other effects in Eff pipelines.

Generated Effect Methods

// Generated on OrderEvents
public static Eff<RT, Unit> Enqueue<RT>(OrderPlaced evt) where RT : struct, IHasOrderEvents => ...
public static Eff<RT, EventAcknowledgement> EnqueueWithAck<RT>(OrderPlaced evt) where RT : struct, IHasOrderEvents => ...
public static Eff<RT, Unit> EnqueueAndWait<RT>(OrderPlaced evt) where RT : struct, IHasOrderEvents => ...

Each method is generic over RT and constrained to IHasOrderEvents — the capability interface generated for this queue.

Capability Interface

The generator produces a capability interface that runtimes must implement:

// Generated
public interface IHasOrderEvents
{
    EventQueueChannel<OrderEvent> OrderEventsChannel { get; }
}

Compose this with your runtime using [Runtime] and [Uses]:

[Runtime]
[Uses<IHasOrderEvents>]
[Uses<IHasNotifications>]
public readonly partial struct AppRuntime;

Effect Pipeline Examples

The generated effect methods compose naturally with other effects:

from created in OrderCommands.Handle(cmd)
from _ in OrderEvents.Enqueue<AppRuntime>(new OrderPlaced(created.Id, cmd.CustomerId))
select created;

Chain multiple queue operations:

OrderEvents.Enqueue<AppRuntime>(new OrderPlaced(order.Id, order.CustomerId))
>> NotificationEvents.Enqueue<AppRuntime>(new NotifyCustomer(order.CustomerId))
>> AuditEvents.Enqueue<AppRuntime>(new AuditRecord("OrderPlaced", order.Id));

Use acknowledgement within an effect pipeline:

from ack in OrderEvents.EnqueueWithAck<AppRuntime>(new OrderPlaced("ord-1", "cust-1"))
from _ in liftEff(async () => await ack.WaitAsync())
          >> NotificationEffects.Send<AppRuntime>("Order confirmed")
select unit;