Reactor
View Sourcereactor
The top-level reactor DSL
Nested DSLs
- middleware
- argument
- wait_for
- where
- guard
- argument
- wait_for
- where
- guard
- argument
- wait_for
- where
- guard
- argument
- wait_for
- where
- guard
- argument
- wait_for
- where
- guard
- argument
- wait_for
- where
- guard
- argument
- wait_for
- where
- guard
- argument
- wait_for
- where
- guard
- argument
- wait_for
- where
- guard
matches?
default
- argument
- wait_for
- where
- guard
Options
| Name | Type | Default | Docs |
|---|---|---|---|
return | atom | Specify which step result to return upon completion. | |
description | String.t | An optional description for the Reactor. |
reactor.middlewares
Middleware to be added to the Reactor
Nested DSLs
reactor.middlewares.middleware
middleware moduleName a middleware to be added to the Reactor.
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
module | module | The middleware to be added to the Reactor. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description for the middleware. |
Introspection
Target: Reactor.Dsl.Middleware
reactor.around
around name, fun \\ nilWrap a function around a group of steps.
Nested DSLs
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique name for the group of steps. | |
fun | (any, any, any, any -> any) | mfa | The around function. See Reactor.Step.Around for more information. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description for the step. | |
allow_async? | boolean | false | Whether the emitted steps should be allowed to run asynchronously. |
reactor.around.argument
argument name, source \\ nilSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | The name of the argument which will be used as the key in the arguments map passed to the implementation. | |
source | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | What to use as the source of the argument. See Reactor.Dsl.Argument for more information. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | nil | An optional description for the argument. | |
transform | (any -> any) | module | nil | An 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 namesWait for the named step to complete before allowing this one to start.
Desugars to argument :_, result(step_to_wait_for)
Examples
wait_for :create_userArguments
| Name | Type | Default | Docs |
|---|---|---|---|
names | atom | list(atom) | The name of the step to wait for. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description. |
Introspection
Target: Reactor.Dsl.WaitFor
reactor.around.where
where predicateOnly execute the surrounding step if the predicate function returns true.
This is a simple version of guard which provides more flexibility at the cost of complexity.
Examples
step :read_file do
argument :path, input(:path)
run &File.read(&1.path)
where &File.exists?(&1.path)
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
predicate | (any -> any) | mfa | (any, any -> any) | mfa | Provide a function which takes the step arguments and optionally the context and returns a boolean value. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Where
reactor.around.guard
guard funProvides a flexible method for conditionally executing a step, or replacing it's result.
Expects a two arity function which takes the step's arguments and context and returns one of the following:
:cont- the guard has passed.{:halt, result}- the guard has failed - instead of executing the step use the provided result.
Examples
step :read_file_via_cache do
argument :path, input(:path)
run &File.read(&1.path)
guard fn %{path: path}, %{cache: cache} ->
case Cache.get(cache, path) do
{:ok, content} -> {:halt, {:ok, content}}
_ -> :cont
end
end
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
fun | (any, any -> any) | mfa | The guard function. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Guard
Introspection
Target: Reactor.Dsl.Around
reactor.collect
collect nameA 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description for the step. | |
transform | (any -> any) | module | nil | An optional transformation function which can be used to modify the entire argument map before it is returned. |
reactor.collect.argument
argument name, source \\ nilSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | The name of the argument which will be used as the key in the arguments map passed to the implementation. | |
source | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | What to use as the source of the argument. See Reactor.Dsl.Argument for more information. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | nil | An optional description for the argument. | |
transform | (any -> any) | module | nil | An 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 namesWait for the named step to complete before allowing this one to start.
Desugars to argument :_, result(step_to_wait_for)
Examples
wait_for :create_userArguments
| Name | Type | Default | Docs |
|---|---|---|---|
names | atom | list(atom) | The name of the step to wait for. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description. |
Introspection
Target: Reactor.Dsl.WaitFor
reactor.collect.where
where predicateOnly execute the surrounding step if the predicate function returns true.
This is a simple version of guard which provides more flexibility at the cost of complexity.
Examples
step :read_file do
argument :path, input(:path)
run &File.read(&1.path)
where &File.exists?(&1.path)
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
predicate | (any -> any) | mfa | (any, any -> any) | mfa | Provide a function which takes the step arguments and optionally the context and returns a boolean value. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Where
reactor.collect.guard
guard funProvides a flexible method for conditionally executing a step, or replacing it's result.
Expects a two arity function which takes the step's arguments and context and returns one of the following:
:cont- the guard has passed.{:halt, result}- the guard has failed - instead of executing the step use the provided result.
Examples
step :read_file_via_cache do
argument :path, input(:path)
run &File.read(&1.path)
guard fn %{path: path}, %{cache: cache} ->
case Cache.get(cache, path) do
{:ok, content} -> {:halt, {:ok, content}}
_ -> :cont
end
end
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
fun | (any, any -> any) | mfa | The guard function. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Guard
Introspection
Target: Reactor.Dsl.Collect
reactor.compose
compose name, reactorCompose another Reactor into this one.
Allows place another Reactor into this one as if it were a single step.
Example
compose :create_user, UserReactor do argument :name, input(:user_name) argument :email, input(:user_email) allow_async? false end
Nested DSLs
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique name for the step. Allows the result of the composed reactor to be depended upon by steps in this reactor. | |
reactor | Reactor | module | The reactor module or struct to compose upon. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description for the step. | |
allow_async? | boolean | true | Whether the composed reactor is allowed to run its steps asynchronously. |
async? | boolean | true | Whether the composed steps should be run asynchronously. |
support_undo? | boolean | true | Whether the composed reactor should also be undone on failure. |
reactor.compose.argument
argument name, source \\ nilSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | The name of the argument which will be used as the key in the arguments map passed to the implementation. | |
source | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | What to use as the source of the argument. See Reactor.Dsl.Argument for more information. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | nil | An optional description for the argument. | |
transform | (any -> any) | module | nil | An 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 namesWait for the named step to complete before allowing this one to start.
Desugars to argument :_, result(step_to_wait_for)
Examples
wait_for :create_userArguments
| Name | Type | Default | Docs |
|---|---|---|---|
names | atom | list(atom) | The name of the step to wait for. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description. |
Introspection
Target: Reactor.Dsl.WaitFor
reactor.compose.where
where predicateOnly execute the surrounding step if the predicate function returns true.
This is a simple version of guard which provides more flexibility at the cost of complexity.
Examples
step :read_file do
argument :path, input(:path)
run &File.read(&1.path)
where &File.exists?(&1.path)
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
predicate | (any -> any) | mfa | (any, any -> any) | mfa | Provide a function which takes the step arguments and optionally the context and returns a boolean value. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Where
reactor.compose.guard
guard funProvides a flexible method for conditionally executing a step, or replacing it's result.
Expects a two arity function which takes the step's arguments and context and returns one of the following:
:cont- the guard has passed.{:halt, result}- the guard has failed - instead of executing the step use the provided result.
Examples
step :read_file_via_cache do
argument :path, input(:path)
run &File.read(&1.path)
guard fn %{path: path}, %{cache: cache} ->
case Cache.get(cache, path) do
{:ok, content} -> {:halt, {:ok, content}}
_ -> :cont
end
end
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
fun | (any, any -> any) | mfa | The guard function. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Guard
Introspection
Target: Reactor.Dsl.Compose
reactor.debug
debug nameInserts a step which will send debug information to the Logger.
Nested DSLs
Examples
debug :debug do
argument :suss, result(:suss_step)
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique identifier for the step. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
level | :emergency | :alert | :critical | :error | :warning | :notice | :info | :debug | :debug | The log level to send the debug information to. |
description | String.t | An optional description for the step. |
reactor.debug.argument
argument name, source \\ nilSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | The name of the argument which will be used as the key in the arguments map passed to the implementation. | |
source | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | What to use as the source of the argument. See Reactor.Dsl.Argument for more information. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | nil | An optional description for the argument. | |
transform | (any -> any) | module | nil | An 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 namesWait for the named step to complete before allowing this one to start.
Desugars to argument :_, result(step_to_wait_for)
Examples
wait_for :create_userArguments
| Name | Type | Default | Docs |
|---|---|---|---|
names | atom | list(atom) | The name of the step to wait for. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description. |
Introspection
Target: Reactor.Dsl.WaitFor
reactor.debug.where
where predicateOnly execute the surrounding step if the predicate function returns true.
This is a simple version of guard which provides more flexibility at the cost of complexity.
Examples
step :read_file do
argument :path, input(:path)
run &File.read(&1.path)
where &File.exists?(&1.path)
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
predicate | (any -> any) | mfa | (any, any -> any) | mfa | Provide a function which takes the step arguments and optionally the context and returns a boolean value. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Where
reactor.debug.guard
guard funProvides a flexible method for conditionally executing a step, or replacing it's result.
Expects a two arity function which takes the step's arguments and context and returns one of the following:
:cont- the guard has passed.{:halt, result}- the guard has failed - instead of executing the step use the provided result.
Examples
step :read_file_via_cache do
argument :path, input(:path)
run &File.read(&1.path)
guard fn %{path: path}, %{cache: cache} ->
case Cache.get(cache, path) do
{:ok, content} -> {:halt, {:ok, content}}
_ -> :cont
end
end
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
fun | (any, any -> any) | mfa | The guard function. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Guard
Introspection
Target: Reactor.Dsl.Debug
reactor.flunk
flunk name, messageCreates 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps. | |
message | nil | String.t | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | The message to to attach to the exception. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description for the step. |
reactor.flunk.argument
argument name, source \\ nilSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | The name of the argument which will be used as the key in the arguments map passed to the implementation. | |
source | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | What to use as the source of the argument. See Reactor.Dsl.Argument for more information. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | nil | An optional description for the argument. | |
transform | (any -> any) | module | nil | An 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 namesWait for the named step to complete before allowing this one to start.
Desugars to argument :_, result(step_to_wait_for)
Examples
wait_for :create_userArguments
| Name | Type | Default | Docs |
|---|---|---|---|
names | atom | list(atom) | The name of the step to wait for. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description. |
Introspection
Target: Reactor.Dsl.WaitFor
reactor.flunk.where
where predicateOnly execute the surrounding step if the predicate function returns true.
This is a simple version of guard which provides more flexibility at the cost of complexity.
Examples
step :read_file do
argument :path, input(:path)
run &File.read(&1.path)
where &File.exists?(&1.path)
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
predicate | (any -> any) | mfa | (any, any -> any) | mfa | Provide a function which takes the step arguments and optionally the context and returns a boolean value. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Where
reactor.flunk.guard
guard funProvides a flexible method for conditionally executing a step, or replacing it's result.
Expects a two arity function which takes the step's arguments and context and returns one of the following:
:cont- the guard has passed.{:halt, result}- the guard has failed - instead of executing the step use the provided result.
Examples
step :read_file_via_cache do
argument :path, input(:path)
run &File.read(&1.path)
guard fn %{path: path}, %{cache: cache} ->
case Cache.get(cache, path) do
{:ok, content} -> {:halt, {:ok, content}}
_ -> :cont
end
end
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
fun | (any, any -> any) | mfa | The guard function. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Guard
Introspection
Target: Reactor.Dsl.Flunk
reactor.group
group nameCall functions before and after a group of steps.
Nested DSLs
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique name for the group of steps. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
before_all | (any, any, any -> any) | mfa | The before function. See Reactor.Step.Group for more information. | |
after_all | (any -> any) | mfa | The after function. See Reactor.Step.Group for more information. | |
allow_async? | boolean | true | Whether the emitted steps should be allowed to run asynchronously. |
description | String.t | An optional description for the step. |
reactor.group.argument
argument name, source \\ nilSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | The name of the argument which will be used as the key in the arguments map passed to the implementation. | |
source | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | What to use as the source of the argument. See Reactor.Dsl.Argument for more information. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | nil | An optional description for the argument. | |
transform | (any -> any) | module | nil | An 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 namesWait for the named step to complete before allowing this one to start.
Desugars to argument :_, result(step_to_wait_for)
Examples
wait_for :create_userArguments
| Name | Type | Default | Docs |
|---|---|---|---|
names | atom | list(atom) | The name of the step to wait for. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description. |
Introspection
Target: Reactor.Dsl.WaitFor
reactor.group.where
where predicateOnly execute the surrounding step if the predicate function returns true.
This is a simple version of guard which provides more flexibility at the cost of complexity.
Examples
step :read_file do
argument :path, input(:path)
run &File.read(&1.path)
where &File.exists?(&1.path)
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
predicate | (any -> any) | mfa | (any, any -> any) | mfa | Provide a function which takes the step arguments and optionally the context and returns a boolean value. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Where
reactor.group.guard
guard funProvides a flexible method for conditionally executing a step, or replacing it's result.
Expects a two arity function which takes the step's arguments and context and returns one of the following:
:cont- the guard has passed.{:halt, result}- the guard has failed - instead of executing the step use the provided result.
Examples
step :read_file_via_cache do
argument :path, input(:path)
run &File.read(&1.path)
guard fn %{path: path}, %{cache: cache} ->
case Cache.get(cache, path) do
{:ok, content} -> {:halt, {:ok, content}}
_ -> :cont
end
end
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
fun | (any, any -> any) | mfa | The guard function. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Guard
Introspection
Target: Reactor.Dsl.Group
reactor.input
input nameSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique name for this input. Used to allow steps to depend on it. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
transform | (any -> any) | module | nil | An optional transformation function which can be used to modify the input before it is passed to any steps. | |
description | String.t | An optional description for the input. |
Introspection
Target: Reactor.Dsl.Input
reactor.map
map nameExecute 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
source 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
source 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique name for the step. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
source | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | The iterator or enumerable to use as the source of the iteration. | |
allow_async? | boolean | false | Whether the emitted steps should be allowed to run asynchronously. |
batch_size | pos_integer | 100 | The number of items to consume off the source when emitting steps. |
description | String.t | An optional description for the step. | |
return | atom | The name of the nested step to use as the return value. | |
strict_ordering? | boolean | true | Whether the mapped values must be returned in the same order that they were provided. |
reactor.map.argument
argument name, source \\ nilSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | The name of the argument which will be used as the key in the arguments map passed to the implementation. | |
source | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | What to use as the source of the argument. See Reactor.Dsl.Argument for more information. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | nil | An optional description for the argument. | |
transform | (any -> any) | module | nil | An 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 namesWait for the named step to complete before allowing this one to start.
Desugars to argument :_, result(step_to_wait_for)
Examples
wait_for :create_userArguments
| Name | Type | Default | Docs |
|---|---|---|---|
names | atom | list(atom) | The name of the step to wait for. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description. |
Introspection
Target: Reactor.Dsl.WaitFor
reactor.map.where
where predicateOnly execute the surrounding step if the predicate function returns true.
This is a simple version of guard which provides more flexibility at the cost of complexity.
Examples
step :read_file do
argument :path, input(:path)
run &File.read(&1.path)
where &File.exists?(&1.path)
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
predicate | (any -> any) | mfa | (any, any -> any) | mfa | Provide a function which takes the step arguments and optionally the context and returns a boolean value. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Where
reactor.map.guard
guard funProvides a flexible method for conditionally executing a step, or replacing it's result.
Expects a two arity function which takes the step's arguments and context and returns one of the following:
:cont- the guard has passed.{:halt, result}- the guard has failed - instead of executing the step use the provided result.
Examples
step :read_file_via_cache do
argument :path, input(:path)
run &File.read(&1.path)
guard fn %{path: path}, %{cache: cache} ->
case Cache.get(cache, path) do
{:ok, content} -> {:halt, {:ok, content}}
_ -> :cont
end
end
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
fun | (any, any -> any) | mfa | The guard function. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Guard
Introspection
Target: Reactor.Dsl.Map
reactor.recurse
recurse name, reactorExecute a reactor recursively until an exit condition is met or maximum iterations are reached.
Allows the output of one iteration to become the input of the next. The reactor must have input/output compatibility to ensure that the outputs from iteration i can be fed into iteration i+1.
Nested DSLs
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique name for the step. Allows the result of the recursed reactor to be depended upon by steps in this reactor. | |
reactor | Reactor | module | The reactor module or struct to recurse on. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description for the step. | |
async? | boolean | true | Whether the recursed steps should be run asynchronously. |
max_iterations | pos_integer | The maximum number of iterations to execute. If not specified, will rely solely on exit_condition. | |
exit_condition | nil | (any -> any) | mfa | A function that takes the result of an iteration and returns a boolean. When true, the recursion will stop. If not provided, will rely solely on max_iterations. |
reactor.recurse.argument
argument name, source \\ nilSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | The name of the argument which will be used as the key in the arguments map passed to the implementation. | |
source | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | What to use as the source of the argument. See Reactor.Dsl.Argument for more information. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | nil | An optional description for the argument. | |
transform | (any -> any) | module | nil | An optional transformation function which can be used to modify the argument before it is passed to the step. |
Introspection
Target: Reactor.Dsl.Argument
reactor.recurse.wait_for
wait_for namesWait for the named step to complete before allowing this one to start.
Desugars to argument :_, result(step_to_wait_for)
Examples
wait_for :create_userArguments
| Name | Type | Default | Docs |
|---|---|---|---|
names | atom | list(atom) | The name of the step to wait for. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description. |
Introspection
Target: Reactor.Dsl.WaitFor
reactor.recurse.where
where predicateOnly execute the surrounding step if the predicate function returns true.
This is a simple version of guard which provides more flexibility at the cost of complexity.
Examples
step :read_file do
argument :path, input(:path)
run &File.read(&1.path)
where &File.exists?(&1.path)
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
predicate | (any -> any) | mfa | (any, any -> any) | mfa | Provide a function which takes the step arguments and optionally the context and returns a boolean value. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Where
reactor.recurse.guard
guard funProvides a flexible method for conditionally executing a step, or replacing it's result.
Expects a two arity function which takes the step's arguments and context and returns one of the following:
:cont- the guard has passed.{:halt, result}- the guard has failed - instead of executing the step use the provided result.
Examples
step :read_file_via_cache do
argument :path, input(:path)
run &File.read(&1.path)
guard fn %{path: path}, %{cache: cache} ->
case Cache.get(cache, path) do
{:ok, content} -> {:halt, {:ok, content}}
_ -> :cont
end
end
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
fun | (any, any -> any) | mfa | The guard function. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Guard
Introspection
Target: Reactor.Dsl.Recurse
reactor.step
step name, impl \\ nilSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps. | |
impl | module | nil | A module that implements the Reactor.Step behaviour that provides the implementation. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description for the step. | |
run | (any -> any) | mfa | (any, any -> any) | mfa | Provide 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) | mfa | Provide 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) | mfa | Provide an anonymous function which implements a compensate/1..3 callback. Cannot be provided at the same time as the impl argument. | |
backoff | (any -> any) | mfa | (any, any -> any) | mfa | (any, any, any -> any) | mfa | Provide an anonymous function which implements a backoff/1..3 callback. Cannot be provided at the same time as the impl argument. | |
max_retries | :infinity | non_neg_integer | :infinity | The maximum number of times that the step can be retried before failing. Only used when the result of the compensate callback is :retry. |
async? | boolean | true | When set to true the step will be executed asynchronously via Reactor's TaskSupervisor. |
transform | (any -> any) | module | nil | An 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 \\ nilSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | The name of the argument which will be used as the key in the arguments map passed to the implementation. | |
source | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | What to use as the source of the argument. See Reactor.Dsl.Argument for more information. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | nil | An optional description for the argument. | |
transform | (any -> any) | module | nil | An 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 namesWait for the named step to complete before allowing this one to start.
Desugars to argument :_, result(step_to_wait_for)
Examples
wait_for :create_userArguments
| Name | Type | Default | Docs |
|---|---|---|---|
names | atom | list(atom) | The name of the step to wait for. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description. |
Introspection
Target: Reactor.Dsl.WaitFor
reactor.step.where
where predicateOnly execute the surrounding step if the predicate function returns true.
This is a simple version of guard which provides more flexibility at the cost of complexity.
Examples
step :read_file do
argument :path, input(:path)
run &File.read(&1.path)
where &File.exists?(&1.path)
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
predicate | (any -> any) | mfa | (any, any -> any) | mfa | Provide a function which takes the step arguments and optionally the context and returns a boolean value. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Where
reactor.step.guard
guard funProvides a flexible method for conditionally executing a step, or replacing it's result.
Expects a two arity function which takes the step's arguments and context and returns one of the following:
:cont- the guard has passed.{:halt, result}- the guard has failed - instead of executing the step use the provided result.
Examples
step :read_file_via_cache do
argument :path, input(:path)
run &File.read(&1.path)
guard fn %{path: path}, %{cache: cache} ->
case Cache.get(cache, path) do
{:ok, content} -> {:halt, {:ok, content}}
_ -> :cont
end
end
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
fun | (any, any -> any) | mfa | The guard function. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Guard
Introspection
Target: Reactor.Dsl.Step
reactor.switch
switch nameUse a predicate to determine which steps should be executed.
Nested DSLs
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique name for the switch. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
on | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | The value to match against. | |
description | String.t | An optional description for the step. | |
allow_async? | boolean | true | Whether the emitted steps should be allowed to run asynchronously. |
reactor.switch.matches?
matches? predicateA group of steps to run when the predicate matches.
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
predicate | (any -> any) | mfa | A 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
| Name | Type | Default | Docs |
|---|---|---|---|
allow_async? | boolean | true | Whether the emitted steps should be allowed to run asynchronously. |
return | atom | Specify 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
| Name | Type | Default | Docs |
|---|---|---|---|
return | atom | Specify which step result to return upon completion. |
Introspection
Target: Reactor.Dsl.Switch.Default
Introspection
Target: Reactor.Dsl.Switch
reactor.template
template nameA step which passes all it's arguments as assigns into an EEx template and returns the result.
Nested DSLs
Examples
template :welcome_message do
arguments :user
template """
Welcome <%= @user.name %>! 🎉
"""
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | A unique name for the step. Used when choosing the return value of the Reactor and for arguments into other steps. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
template | String.t | An EEx template. | |
description | String.t | An optional description for the step. |
reactor.template.argument
argument name, source \\ nilSpecifies 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
| Name | Type | Default | Docs |
|---|---|---|---|
name | atom | The name of the argument which will be used as the key in the arguments map passed to the implementation. | |
source | Reactor.Template.Element | Reactor.Template.Input | Reactor.Template.Result | Reactor.Template.Value | What to use as the source of the argument. See Reactor.Dsl.Argument for more information. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | nil | An optional description for the argument. | |
transform | (any -> any) | module | nil | An optional transformation function which can be used to modify the argument before it is passed to the step. |
Introspection
Target: Reactor.Dsl.Argument
reactor.template.wait_for
wait_for namesWait for the named step to complete before allowing this one to start.
Desugars to argument :_, result(step_to_wait_for)
Examples
wait_for :create_userArguments
| Name | Type | Default | Docs |
|---|---|---|---|
names | atom | list(atom) | The name of the step to wait for. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description. |
Introspection
Target: Reactor.Dsl.WaitFor
reactor.template.where
where predicateOnly execute the surrounding step if the predicate function returns true.
This is a simple version of guard which provides more flexibility at the cost of complexity.
Examples
step :read_file do
argument :path, input(:path)
run &File.read(&1.path)
where &File.exists?(&1.path)
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
predicate | (any -> any) | mfa | (any, any -> any) | mfa | Provide a function which takes the step arguments and optionally the context and returns a boolean value. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Where
reactor.template.guard
guard funProvides a flexible method for conditionally executing a step, or replacing it's result.
Expects a two arity function which takes the step's arguments and context and returns one of the following:
:cont- the guard has passed.{:halt, result}- the guard has failed - instead of executing the step use the provided result.
Examples
step :read_file_via_cache do
argument :path, input(:path)
run &File.read(&1.path)
guard fn %{path: path}, %{cache: cache} ->
case Cache.get(cache, path) do
{:ok, content} -> {:halt, {:ok, content}}
_ -> :cont
end
end
end
Arguments
| Name | Type | Default | Docs |
|---|---|---|---|
fun | (any, any -> any) | mfa | The guard function. |
Options
| Name | Type | Default | Docs |
|---|---|---|---|
description | String.t | An optional description of the guard. |
Introspection
Target: Reactor.Dsl.Guard
Introspection
Target: Reactor.Dsl.Template