View Source DSL: Reactor.Dsl

reactor

The top-level reactor DSL

Nested DSLs

Options

NameTypeDefaultDocs
returnatomSpecify which step result to return upon completion.

reactor.middlewares

Middleware to be added to the Reactor

Nested DSLs

reactor.middlewares.middleware

middleware module

Name a middleware to be added to the Reactor.

Arguments

NameTypeDefaultDocs
modulemoduleThe middleware to be added to the Reactor.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the middleware.

Introspection

Target: Reactor.Dsl.Middleware

reactor.around

around name, fun \\ nil

Wrap a function around a group of steps.

Nested DSLs

Arguments

NameTypeDefaultDocs
nameatomA unique name for the group of steps.
fun(any, any, any, any -> any) | mfaThe around function. See Reactor.Step.Around for more information.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the step.
allow_async?booleanfalseWhether the emitted steps should be allowed to run asynchronously.

reactor.around.argument

argument name, source \\ nil

Specifies an argument to a Reactor step.

Each argument is a value which is either the result of another step, or an input value.

Individual arguments can be transformed with an arbitrary function before being passed to any steps.

Examples

argument :name, input(:name)
argument :year, input(:date, [:year])
argument :user, result(:create_user)
argument :user_id, result(:create_user) do
  transform & &1.id
end
argument :user_id, result(:create_user, [:id])
argument :three, value(3)

Arguments

NameTypeDefaultDocs
nameatomThe name of the argument which will be used as the key in the arguments map passed to the implementation.
sourceReactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.ValueWhat to use as the source of the argument. See Reactor.Dsl.Argument for more information.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the argument.
transform(any -> any) | module | nilAn optional transformation function which can be used to modify the argument before it is passed to the step.

Introspection

Target: Reactor.Dsl.Argument

reactor.around.wait_for

wait_for names

Wait for the named step to complete before allowing this one to start.

Desugars to argument :_, result(step_to_wait_for)

Examples

wait_for :create_user

Arguments

NameTypeDefaultDocs
namesatom | list(atom)The name of the step to wait for.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description.

Introspection

Target: Reactor.Dsl.WaitFor

Introspection

Target: Reactor.Dsl.Around

reactor.collect

collect name

A Reactor step which simply collects and returns it's arguments.

Arguments can optionally be transformed before returning.

Nested DSLs

Examples

collect :latest_release_uri do
  argument :repository, input(:repository)
  argument :organisation, input(:organisation)

  transform fn inputs ->
    %{uri: "https://api.github.com/repos/#{inputs.organisation}/#{inputs.repository}/releases/latest"}
  end
end

Arguments

NameTypeDefaultDocs
nameatomA unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the step.
transform(any -> any) | module | nilAn optional transformation function which can be used to modify the entire argument map before it is returned.

reactor.collect.argument

argument name, source \\ nil

Specifies an argument to a Reactor step.

Each argument is a value which is either the result of another step, or an input value.

Individual arguments can be transformed with an arbitrary function before being passed to any steps.

Examples

argument :name, input(:name)
argument :year, input(:date, [:year])
argument :user, result(:create_user)
argument :user_id, result(:create_user) do
  transform & &1.id
end
argument :user_id, result(:create_user, [:id])
argument :three, value(3)

Arguments

NameTypeDefaultDocs
nameatomThe name of the argument which will be used as the key in the arguments map passed to the implementation.
sourceReactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.ValueWhat to use as the source of the argument. See Reactor.Dsl.Argument for more information.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the argument.
transform(any -> any) | module | nilAn optional transformation function which can be used to modify the argument before it is passed to the step.

Introspection

Target: Reactor.Dsl.Argument

reactor.collect.wait_for

wait_for names

Wait for the named step to complete before allowing this one to start.

Desugars to argument :_, result(step_to_wait_for)

Examples

wait_for :create_user

Arguments

NameTypeDefaultDocs
namesatom | list(atom)The name of the step to wait for.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description.

Introspection

Target: Reactor.Dsl.WaitFor

Introspection

Target: Reactor.Dsl.Collect

reactor.compose

compose name, reactor

Compose another Reactor into this one.

Allows place another Reactor into this one as if it were a single step.

Nested DSLs

Arguments

NameTypeDefaultDocs
nameatomA unique name for the step. Allows the result of the composed reactor to be depended upon by steps in this reactor.
reactorReactor | moduleThe reactor module or struct to compose upon.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the step.

reactor.compose.argument

argument name, source \\ nil

Specifies an argument to a Reactor step.

Each argument is a value which is either the result of another step, or an input value.

Individual arguments can be transformed with an arbitrary function before being passed to any steps.

Examples

argument :name, input(:name)
argument :year, input(:date, [:year])
argument :user, result(:create_user)
argument :user_id, result(:create_user) do
  transform & &1.id
end
argument :user_id, result(:create_user, [:id])
argument :three, value(3)

Arguments

NameTypeDefaultDocs
nameatomThe name of the argument which will be used as the key in the arguments map passed to the implementation.
sourceReactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.ValueWhat to use as the source of the argument. See Reactor.Dsl.Argument for more information.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the argument.
transform(any -> any) | module | nilAn optional transformation function which can be used to modify the argument before it is passed to the step.

Introspection

Target: Reactor.Dsl.Argument

reactor.compose.wait_for

wait_for names

Wait for the named step to complete before allowing this one to start.

Desugars to argument :_, result(step_to_wait_for)

Examples

wait_for :create_user

Arguments

NameTypeDefaultDocs
namesatom | list(atom)The name of the step to wait for.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description.

Introspection

Target: Reactor.Dsl.WaitFor

Introspection

Target: Reactor.Dsl.Compose

reactor.debug

debug name

Inserts a step which will send debug information to the Logger.

Nested DSLs

Examples

debug :debug do
  argument :suss, result(:suss_step)
end

Arguments

NameTypeDefaultDocs
nameatomA unique identifier for the step.

Options

NameTypeDefaultDocs
level:emergency | :alert | :critical | :error | :warning | :notice | :info | :debug:debugThe log level to send the debug information to.

reactor.debug.argument

argument name, source \\ nil

Specifies an argument to a Reactor step.

Each argument is a value which is either the result of another step, or an input value.

Individual arguments can be transformed with an arbitrary function before being passed to any steps.

Examples

argument :name, input(:name)
argument :year, input(:date, [:year])
argument :user, result(:create_user)
argument :user_id, result(:create_user) do
  transform & &1.id
end
argument :user_id, result(:create_user, [:id])
argument :three, value(3)

Arguments

NameTypeDefaultDocs
nameatomThe name of the argument which will be used as the key in the arguments map passed to the implementation.
sourceReactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.ValueWhat to use as the source of the argument. See Reactor.Dsl.Argument for more information.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the argument.
transform(any -> any) | module | nilAn optional transformation function which can be used to modify the argument before it is passed to the step.

Introspection

Target: Reactor.Dsl.Argument

reactor.debug.wait_for

wait_for names

Wait for the named step to complete before allowing this one to start.

Desugars to argument :_, result(step_to_wait_for)

Examples

wait_for :create_user

Arguments

NameTypeDefaultDocs
namesatom | list(atom)The name of the step to wait for.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description.

Introspection

Target: Reactor.Dsl.WaitFor

Introspection

Target: Reactor.Dsl.Debug

reactor.flunk

flunk name, message

Creates a step which will always cause the Reactor to exit with an error.

This step will flunk with a Reactor.Error.Invalid.ForcedFailureError with it's message set to the provided message. Additionally, any arguments to the step will be stored in the exception under the arguments key.

Nested DSLs

Examples

flunk :outaroad, "Ran out of road before reaching 88Mph"

Arguments

NameTypeDefaultDocs
nameatomA unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps.
messagenil | String.t | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.ValueThe message to to attach to the exception.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the step.

reactor.flunk.argument

argument name, source \\ nil

Specifies an argument to a Reactor step.

Each argument is a value which is either the result of another step, or an input value.

Individual arguments can be transformed with an arbitrary function before being passed to any steps.

Examples

argument :name, input(:name)
argument :year, input(:date, [:year])
argument :user, result(:create_user)
argument :user_id, result(:create_user) do
  transform & &1.id
end
argument :user_id, result(:create_user, [:id])
argument :three, value(3)

Arguments

NameTypeDefaultDocs
nameatomThe name of the argument which will be used as the key in the arguments map passed to the implementation.
sourceReactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.ValueWhat to use as the source of the argument. See Reactor.Dsl.Argument for more information.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the argument.
transform(any -> any) | module | nilAn optional transformation function which can be used to modify the argument before it is passed to the step.

Introspection

Target: Reactor.Dsl.Argument

reactor.flunk.wait_for

wait_for names

Wait for the named step to complete before allowing this one to start.

Desugars to argument :_, result(step_to_wait_for)

Examples

wait_for :create_user

Arguments

NameTypeDefaultDocs
namesatom | list(atom)The name of the step to wait for.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description.

Introspection

Target: Reactor.Dsl.WaitFor

Introspection

Target: Reactor.Dsl.Flunk

reactor.group

group name

Call functions before and after a group of steps.

Nested DSLs

Arguments

NameTypeDefaultDocs
nameatomA unique name for the group of steps.

Options

NameTypeDefaultDocs
before_all(any, any, any -> any) | mfaThe before function. See Reactor.Step.Group for more information.
after_all(any -> any) | mfaThe after function. See Reactor.Step.Group for more information.
allow_async?booleantrueWhether the emitted steps should be allowed to run asynchronously.
descriptionString.tAn optional description for the step.

reactor.group.argument

argument name, source \\ nil

Specifies an argument to a Reactor step.

Each argument is a value which is either the result of another step, or an input value.

Individual arguments can be transformed with an arbitrary function before being passed to any steps.

Examples

argument :name, input(:name)
argument :year, input(:date, [:year])
argument :user, result(:create_user)
argument :user_id, result(:create_user) do
  transform & &1.id
end
argument :user_id, result(:create_user, [:id])
argument :three, value(3)

Arguments

NameTypeDefaultDocs
nameatomThe name of the argument which will be used as the key in the arguments map passed to the implementation.
sourceReactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.ValueWhat to use as the source of the argument. See Reactor.Dsl.Argument for more information.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the argument.
transform(any -> any) | module | nilAn optional transformation function which can be used to modify the argument before it is passed to the step.

Introspection

Target: Reactor.Dsl.Argument

reactor.group.wait_for

wait_for names

Wait for the named step to complete before allowing this one to start.

Desugars to argument :_, result(step_to_wait_for)

Examples

wait_for :create_user

Arguments

NameTypeDefaultDocs
namesatom | list(atom)The name of the step to wait for.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description.

Introspection

Target: Reactor.Dsl.WaitFor

Introspection

Target: Reactor.Dsl.Group

reactor.input

input name

Specifies an input to the Reactor.

An input is a value passed in to the Reactor when executing. If a Reactor were a function, these would be it's arguments.

Inputs can be transformed with an arbitrary function before being passed to any steps.

Examples

input :name
input :age do
  transform &String.to_integer/1
end

Arguments

NameTypeDefaultDocs
nameatomA unique name for this input. Used to allow steps to depend on it.

Options

NameTypeDefaultDocs
transform(any -> any) | module | nilAn optional transformation function which can be used to modify the input before it is passed to any steps.
descriptionString.tAn optional description for the input.

Introspection

Target: Reactor.Dsl.Input

reactor.map

map name

Execute nested steps for every item of an iterator.

Allows you to "map over" a collection applying a some steps to each element, returning a list of new values. The input collection must be bounded - ie you cannot pass infinite streams into this step or it will just loop forever - and because it has to keep the results from each batch will eventually just use up all available RAM.

Under the hood we use Iter to handle lazy iteration of the collection. This means that you can pass an Iter.t or any value for which Iter.IntoIterable is implemented.

A note on ordering

If your application doesn't need the results back in the same order that they were provided then setting strict_ordering? to false will increase performance - especially on large input sets.

Nested DSLs

Examples

map :double_numbers do
  input input(:numbers)

  step :double do
    argument :number, element(:double_numbers)

    run fn %{number: number}, _ ->
      {:ok, number * 2}
    end
  end
end
step :get_subscriptions do
  run fn _, _ ->
    Stripe.Subscription.list()
  end
end

map :cancel_subscriptions do
  input result(:get_subscriptions)

  step :cancel do
    argument :sub_id, element(:cancel_subscriptions, [:id])

    run fn args, _ ->
      Stripe.Subscription.cancel(arg.sub_id, %{prorate: true, invoice_now: true})
    end
  end

  return :cancel
end

Arguments

NameTypeDefaultDocs
nameatomA unique name for the step.

Options

NameTypeDefaultDocs
sourceReactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.ValueThe iterator or enumerable to use as the source of the iteration.
allow_async?booleanfalseWhether the emitted steps should be allowed to run asynchronously.
batch_sizepos_integer100The number of items to consume off the source when emitting steps.
descriptionString.tAn optional description for the step.
returnatomThe name of the nested step to use as the return value.
strict_ordering?booleantrueWhether the mapped values must be returned in the same order that they were provided.

reactor.map.argument

argument name, source \\ nil

Specifies an argument to a Reactor step.

Each argument is a value which is either the result of another step, or an input value.

Individual arguments can be transformed with an arbitrary function before being passed to any steps.

Examples

argument :name, input(:name)
argument :year, input(:date, [:year])
argument :user, result(:create_user)
argument :user_id, result(:create_user) do
  transform & &1.id
end
argument :user_id, result(:create_user, [:id])
argument :three, value(3)

Arguments

NameTypeDefaultDocs
nameatomThe name of the argument which will be used as the key in the arguments map passed to the implementation.
sourceReactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.ValueWhat to use as the source of the argument. See Reactor.Dsl.Argument for more information.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the argument.
transform(any -> any) | module | nilAn optional transformation function which can be used to modify the argument before it is passed to the step.

Introspection

Target: Reactor.Dsl.Argument

reactor.map.wait_for

wait_for names

Wait for the named step to complete before allowing this one to start.

Desugars to argument :_, result(step_to_wait_for)

Examples

wait_for :create_user

Arguments

NameTypeDefaultDocs
namesatom | list(atom)The name of the step to wait for.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description.

Introspection

Target: Reactor.Dsl.WaitFor

Introspection

Target: Reactor.Dsl.Map

reactor.step

step name, impl \\ nil

Specifies a Reactor step.

Steps are the unit of work in a Reactor. Reactor will calculate the dependencies graph between the steps and execute as many as it can in each iteration.

See the Reactor.Step behaviour for more information.

Nested DSLs

Examples

step :create_user, MyApp.Steps.CreateUser do
  argument :username, input(:username)
  argument :password_hash, result(:hash_password)
end
step :hash_password do
  argument :password, input(:password)

  run fn %{password: password}, _ ->
    {:ok, Bcrypt.hash_pwd_salt(password)}
  end
end

Arguments

NameTypeDefaultDocs
nameatomA unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps.
implmodule | nilA module that implements the Reactor.Step behaviour that provides the implementation.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the step.
run(any -> any) | mfa | (any, any -> any) | mfaProvide an anonymous function which implements a run/1-2 callback. Cannot be provided at the same time as the impl argument.
undo(any -> any) | mfa | (any, any -> any) | mfa | (any, any, any -> any) | mfaProvide an anonymous function which implements a undo/1-3 callback. Cannot be provided at the same time as the impl argument.
compensate(any -> any) | mfa | (any, any -> any) | mfa | (any, any, any -> any) | mfaProvide an anonymous function which implements a compensate/1-3 callback. Cannot be provided at the same time as the impl argument.
max_retries:infinity | non_neg_integer:infinityThe maximum number of times that the step can be retried before failing. Only used when the result of the compensate callback is :retry.
async?booleantrueWhen set to true the step will be executed asynchronously via Reactor's TaskSupervisor.
transform(any -> any) | module | nilAn optional transformation function which can be used to modify the entire argument map before it is passed to the step.

reactor.step.argument

argument name, source \\ nil

Specifies an argument to a Reactor step.

Each argument is a value which is either the result of another step, or an input value.

Individual arguments can be transformed with an arbitrary function before being passed to any steps.

Examples

argument :name, input(:name)
argument :year, input(:date, [:year])
argument :user, result(:create_user)
argument :user_id, result(:create_user) do
  transform & &1.id
end
argument :user_id, result(:create_user, [:id])
argument :three, value(3)

Arguments

NameTypeDefaultDocs
nameatomThe name of the argument which will be used as the key in the arguments map passed to the implementation.
sourceReactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.ValueWhat to use as the source of the argument. See Reactor.Dsl.Argument for more information.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description for the argument.
transform(any -> any) | module | nilAn optional transformation function which can be used to modify the argument before it is passed to the step.

Introspection

Target: Reactor.Dsl.Argument

reactor.step.wait_for

wait_for names

Wait for the named step to complete before allowing this one to start.

Desugars to argument :_, result(step_to_wait_for)

Examples

wait_for :create_user

Arguments

NameTypeDefaultDocs
namesatom | list(atom)The name of the step to wait for.

Options

NameTypeDefaultDocs
descriptionString.tAn optional description.

Introspection

Target: Reactor.Dsl.WaitFor

Introspection

Target: Reactor.Dsl.Step

reactor.switch

switch name

Use a predicate to determine which steps should be executed.

Nested DSLs

Arguments

NameTypeDefaultDocs
nameatomA unique name for the switch.

Options

NameTypeDefaultDocs
onReactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.ValueThe value to match against.
descriptionString.tAn optional description for the step.
allow_async?booleantrueWhether the emitted steps should be allowed to run asynchronously.

reactor.switch.matches?

matches? predicate

A group of steps to run when the predicate matches.

Arguments

NameTypeDefaultDocs
predicate(any -> any) | mfaA one-arity function which is used to match the switch input. If the switch returns a truthy value, then the nested steps will be run.

Options

NameTypeDefaultDocs
allow_async?booleantrueWhether the emitted steps should be allowed to run asynchronously.
returnatomSpecify which step result to return upon completion.

Introspection

Target: Reactor.Dsl.Switch.Match

reactor.switch.default

If none of the matches? branches match the input, then the default steps will be run if provided.

Options

NameTypeDefaultDocs
returnatomSpecify which step result to return upon completion.

Introspection

Target: Reactor.Dsl.Switch.Default

Introspection

Target: Reactor.Dsl.Switch