ash-project / reactor

Reactor is a dynamic, concurrent, dependency resolving saga orchestrator.
https://ash-hq.org/
MIT License
44 stars 6 forks source link

Steps preceding a 'switch' execute multiple times #132

Open mitel opened 1 day ago

mitel commented 1 day ago

Describe the bug Steps preceding a switch execute multiple times. The code below will output 'MOO' and 'BOO' twice. (It only happens if those steps do not halt). The debug step also executes twice, not sure if that is ok.

To Reproduce

Reactor.run(SwitchReactor, %{value: true})

defmodule SwitchReactor do
  @moduledoc false
  use Reactor

  input :value

  debug :debug do
    argument :value, input(:value)
  end

  step :moo do
    argument :value, input(:value)

    run fn %{value: value}, _ ->
      IO.puts IO.ANSI.format([:yellow_background, :black, "MOOO"])

      {:ok, value}
    end
  end

  step :boo do
    argument :value, input(:value)

    wait_for :moo

    run fn %{value: value}, _ ->
      IO.puts IO.ANSI.format([:yellow_background, :black, "BOOO"])

      {:ok, !value}
    end
  end

  switch :is_truthy? do
    on result(:boo)

    matches? &(&1 in [nil, false]) do
      # step :falsy, Noop

      step :falsy do
        argument :value, input(:value)

        wait_for :boo

        run fn %{value: value}, _ ->
          IO.puts IO.ANSI.format([:yellow_background, :black, "falsy"])

          {:ok, value}
        end
      end

      return :falsy
    end

    default do
      step :truthy, Noop

      return :truthy
    end
  end

  return :is_truthy?
end

Expected behavior The steps should be executed only once.

Runtime

zachdaniel commented 1 day ago

Definitely not desired at all. @jimsynz you have a chance to look into this?