Packages
reactor
0.9.1
1.0.2
1.0.1
1.0.0
0.17.0
0.16.0
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.1
0.9.0
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
An asynchronous, graph-based execution engine
Current section
Files
Jump to
Current section
Files
lib/reactor/dsl/group.ex
defmodule Reactor.Dsl.Group do
@moduledoc """
The `group` DSL entity struct.
See `d:Reactor.group`.
"""
defstruct __identifier__: nil,
allow_async?: false,
arguments: [],
before_all: nil,
after_all: nil,
name: nil,
steps: []
alias Reactor.{Builder, Dsl, Step}
@type t :: %Dsl.Group{
__identifier__: any,
allow_async?: true,
arguments: [Dsl.Argument.t()],
before_all: mfa | Step.Group.before_fun(),
after_all: mfa | Step.Group.after_fun(),
name: atom,
steps: [Dsl.Step.t()]
}
@doc false
def __entity__,
do: %Spark.Dsl.Entity{
name: :group,
describe: """
Call functions before and after a group of steps.
""",
target: Dsl.Group,
args: [:name],
identifier: :name,
entities: [steps: [], arguments: [Dsl.Argument.__entity__(), Dsl.WaitFor.__entity__()]],
recursive_as: :steps,
schema: [
name: [
type: :atom,
required: true,
doc: """
A unique name for the group of steps.
"""
],
before_all: [
type: {:mfa_or_fun, 3},
required: true,
doc: """
The before function. See `Reactor.Step.Group` for more information.
"""
],
after_all: [
type: {:mfa_or_fun, 1},
required: true,
doc: """
The after function. See `Reactor.Step.Group` for more information.
"""
],
allow_async?: [
type: :boolean,
required: false,
default: true,
doc: """
Whether the emitted steps should be allowed to run asynchronously.
"""
]
]
}
defimpl Dsl.Build do
import Reactor.Utils
alias Spark.{Dsl.Verifier, Error.DslError}
def build(group, reactor) do
sub_reactor = Builder.new(reactor.id)
with {:ok, sub_reactor} <- build_inputs(sub_reactor, group),
{:ok, sub_reactor} <- build_steps(sub_reactor, group) do
Builder.add_step(
reactor,
group.name,
{Step.Group,
before: group.before_all,
after: group.after_all,
steps: sub_reactor.steps,
allow_async?: group.allow_async?},
group.arguments,
async?: group.allow_async?,
max_retries: 0,
ref: :step_name
)
end
end
def verify(group, dsl_state) when group.steps == [] do
{:error,
DslError.exception(
module: Verifier.get_persisted(dsl_state, :module),
path: [:reactor, :group, group.name],
message: "Group contains no steps"
)}
end
def verify(group, dsl_state) do
group.steps
|> Enum.reduce_while(:ok, fn step, :ok ->
case Dsl.Build.verify(step, dsl_state) do
:ok -> {:cont, :ok}
{:error, reason} -> {:halt, {:error, reason}}
end
end)
end
defp build_inputs(reactor, group) do
group.arguments
|> Enum.map(& &1.name)
|> reduce_while_ok(reactor, &Builder.add_input(&2, &1))
end
defp build_steps(reactor, group) do
group.steps
|> reduce_while_ok(reactor, &Dsl.Build.build/2)
end
end
end