public static async ValueTask OnStateChangeTo()

in src/DotPulsar/Extensions/StateHolderExtensions.cs [33:105]


    public static async ValueTask<TState> OnStateChangeTo<TState>(
        this IStateHolder<TState> stateHolder,
        TState state,
        TimeSpan delay,
        CancellationToken cancellationToken = default) where TState : notnull
        => await stateHolder.State.OnStateChangeTo(state, delay, cancellationToken);

    /// <summary>
    /// Wait for the state to change from a specific state with a delay.
    /// </summary>
    /// <returns>
    /// The current state.
    /// </returns>
    /// <remarks>
    /// If the state change to a final state, then all awaiting tasks will complete.
    /// </remarks>
    public static async ValueTask<TState> OnStateChangeFrom<TState>(
        this IStateHolder<TState> stateHolder,
        TState state,
        TimeSpan delay,
        CancellationToken cancellationToken = default) where TState : notnull
    => await stateHolder.State.OnStateChangeFrom(state, delay, cancellationToken);

    /// <summary>
    /// Will invoke the onStateLeft callback when the state if left (with delay) and onStateReached when it's reached again.
    /// </summary>
    /// <returns>
    /// ValueTask that will run as long as a final state is not entered.
    /// </returns>
    public static async ValueTask DelayedStateMonitor<TEntity, TState, TFaultContext>(
        this TEntity stateHolder,
        TState state,
        TimeSpan delay,
        Func<TEntity, TState, CancellationToken, ValueTask<TFaultContext>> onStateLeft,
        Func<TEntity, TState, TFaultContext, CancellationToken, ValueTask> onStateReached,
        CancellationToken cancellationToken = default) where TEntity : IStateHolder<TState> where TState : notnull where TFaultContext : class
    {
        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var currentState = await stateHolder.OnStateChangeFrom(state, delay, cancellationToken).ConfigureAwait(false);

            TFaultContext? faultContext = null;

            try
            {
                faultContext = await onStateLeft(stateHolder, currentState, cancellationToken).ConfigureAwait(false);
            }
            catch
            {
                // Ignore
            }

            if (stateHolder.State.IsFinalState(currentState))
                return;

            currentState = await stateHolder.State.OnStateChangeTo(state, cancellationToken).ConfigureAwait(false);

            if (stateHolder.State.IsFinalState(currentState))
                return;

            try
            {
                if (faultContext is not null)
                    await onStateReached(stateHolder, currentState, faultContext, cancellationToken).ConfigureAwait(false);
            }
            catch
            {
                // Ignore
            }
        }
    }