Skip to content

Signals

BL19 edited this page Aug 7, 2026 · 3 revisions

Signals are a way for asynchronous execution of Flows where the Flow can wait for some signal before proceeding with the rest of the Flow.

Working with Signals

To wait for a signal you may use the ctx.WaitForSignal method. This method takes the name of the signal and a correlation key. Both of these as a pair make up the signal identification.

To send the signal you use the ISpindleRuntime.SignalAsync to emit a signal. This will send the signal to all currently listening Flows, if a Flow has yet to register a signal that flow won't get the signal.

Without Data

To wait for a signal while discarding the data you can use the following as an example:

public async ValueTask<Guid> RunAsync(IFlowContext ctx, Unit _)
{
    var order = await ctx.Step(/* Place order */);

    // Wait for the signal that the order has been shipped
    await ctx.WaitForSignal(new SignalName("order.shipped"), new CorrelationKey(order.Id.ToString()));

    await ctx.Step(/* Notify Customer */);

    return order.Id;
}

Elsewhere, you may emit the signal:

public async Task<bool> MarkOrderShippedAsync(Guid id) 
{
    /* Update the order */
    await spindleRuntime.SignalAsync(new SignalName("order.shipped"), new CorrelationKey(id.ToString()));
}

With Data

If your signal has some data attached, that signal is able to get the attached data from the signal when it recieves the signal. Reusing the same example, we may provide the user with some tracking information.

public async ValueTask<Guid> RunAsync(IFlowContext ctx, Unit _)
{
    var order = await ctx.Step(/* Place order */);

    // Wait for the signal that the order has been shipped and capture the tracking information
    var tracking = await ctx.WaitForSignal<OrderTrackingDto>(
            new SignalName("order.shipped"), new CorrelationKey(order.Id.ToString()));

    await ctx.Step(/* Notify Customer with tracking information */);

    return order.Id;
}

And when emitting the signal

public async Task<bool> MarkOrderShippedAsync(Guid id, OrderTrackingDto tracking) 
{
    /* Update the order */

    await spindleRuntime.SignalAsync(
            new SignalName("order.shipped"), 
            new CorrelationKey(id.ToString()),
            tracking);
}

Clone this wiki locally