Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error building Reactor execution graph when using switch with result template helper #136

Closed
mitel opened this issue Nov 10, 2024 · 3 comments · Fixed by #156
Closed

Error building Reactor execution graph when using switch with result template helper #136

mitel opened this issue Nov 10, 2024 · 3 comments · Fixed by #156
Assignees
Labels
bug Something isn't working

Comments

@mitel
Copy link

mitel commented Nov 10, 2024

Describe the bug
The code below fails to compile (after a mix clean). Error:

Step `:my_failing_step` depends on the result of a step named `:boo` which cannot be found

The execution graph cannot find a step outside the switch statement when using the result template helper.

To Reproduce

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

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, result(:moo)

    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 == "zen") do
      # step :falsy, Noop

      step :my_failing_step do
        argument :value, result(:boo)

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

          {:ok, value}
        end
      end

      return :my_failing_step
    end

    default do
      step :anyways, Noop

      return :anyways
    end
  end

  return :is_truthy?
end

Expected behavior
The inner switch step should be able to use the result template helper.

Runtime

  • Elixir version: 1.16.3
  • Erlang version: 26
  • OS: ubuntu-focal-20231003
  • Spark version: 2.2.35
  • reactor 0.10.1

Additional context
After multiple compilations at some point it started to work, but once I did a mix clean it failed again to compile.

@mitel mitel added the bug Something isn't working label Nov 10, 2024
@sbennett33
Copy link

Here's a simpler example that reproduces the same problem:

defmodule Level.Resources.ProvisionUser do
  @moduledoc """
  Provisions a user account.
  """
  use Ash.Reactor

  alias Level.Resources.OnboardingCode

  ash do
    default_domain Level
  end

  input :code

  read_one :onboarding_code, OnboardingCode, :by_code do
    inputs(%{code: input(:code)})
  end

  switch :has_code do
    on result(:onboarding_code)

    matches? &(not is_nil(&1)) do
      debug :debug do
        argument :onboarding_code, result(:onboarding_code)
      end
    end
  end

  return :onboarding_code
end

Generates the following error:

(Reactor.Error.Internal.PlanError) # Reactor Plan Error

An error occurred while building or updating the Reactor execution graph.

Step :debug depends on the result of a step named :onboarding_code which cannot be found

Step

%Reactor.Step{arguments: [%Reactor.Argument{name: :onboarding_code, source: %Reactor.Template.Result{name: :onboarding_code, sub_path: []}, transform: nil}], async?: true, context: %{}, impl: {Reactor.Step.Debug, [level: :debug]}, name: :debug, max_retries: 0, ref: :debug, transform: nil}

Graph

#Graph<type: directed, vertices: [%Reactor.Step{arguments: [%Reactor.Argument{name: :onboarding_code, source: %Reactor.Template.Result{name: :onboarding_code, sub_path: []}, transform: nil}], async?: true, context: %{}, impl: {Reactor.Step.Debug, [level: :debug]}, name: :debug, max_retries: 0, ref: :debug, transform: nil}], edges: []>
(spark 2.2.35) lib/spark/dsl/extension.ex:702: Spark.Dsl.Extension.raise_transformer_error/2
(elixir 1.17.2) lib/enum.ex:4858: Enumerable.List.reduce/3
(elixir 1.17.2) lib/enum.ex:2585: Enum.reduce_while/3
/Users/sbennett/Projects/src/github.com/Level-All/level/lib/level/resources/provision_user_2.ex:1: (file)
(stdlib 6.0.1) erl_eval.erl:904: :erl_eval.do_apply/7
(stdlib 6.0.1) erl_eval.erl:1192: :erl_eval.expr_list/7
(stdlib 6.0.1) erl_eval.erl:610: :erl_eval.expr/6

jimsynz added a commit that referenced this issue Feb 2, 2025
This fixes a bug where a Reactor would fail when steps are added at runtime
which depend on an already computed result.  This is required to fix #136
which stops a Reactor from planning nested switch steps.
@jimsynz jimsynz closed this as completed in 479a3e0 Feb 3, 2025
@jimsynz
Copy link
Contributor

jimsynz commented Feb 3, 2025

@sbennett33, @mitel I'm so sorry about the long delay on this one, but it's fixed in main and I'll be releasing it later on today.

@mitel
Copy link
Author

mitel commented Feb 3, 2025

Thank you!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants