View Source Skitter.DSL.Strategy.Helpers (Skitter v0.7.1)
Macros to be used in strategy hooks.
This module defines various macro "primitives" which can be used to define strategies. These
macros are only available inside Skitter.DSL.Strategy.defhook/2
, where they are automatically
imported.
Internally, these macros call functions defined in various other modules. The information stored
in the Skitter.Strategy.context/0
passed to the hook is used to pass the appropriate
information to these functions.
Summary
Functions
Call callback
of the current operation.
Call callback
of the current operation if it exists.
Emit data for the current context.
Raise a Skitter.StrategyError
Get the index of the given in port
.
Get the name of the in port with the given index
.
Get the name of the out port with the given index
.
Create an empty state for the operation.
Create a worker using Skitter.Worker.create_local/3
.
Get the index of the given out port
.
Send a message to a worker using Elixir's Kernel.send/2
.
Create a worker using Skitter.Worker.create_remote/4
.
Send a message to a worker with Skitter.Worker.send/2
Stop the current worker using Skitter.Worker.stop/1
Stop the given worker using Skitter.Worker.stop/1
Programmatically create output for all out ports.
Programmatically create output for the out port with index
.
Functions
Call callback
of the current operation.
Uses Skitter.Operation.call/5
. The state, configuration and arguments can be passed through
opts. If they are not provided, :args
defaults to the empty list while :state
and :config
default to nil
.
Examples
iex> defoperation ExampleOperation do
...> defcb example(arg), do: {arg, state(), config()}
...> end
iex> defstrategy ExampleStrategy do
...> defhook empty_example(), do: call(:example).result
...> defhook arg_example(), do: call(:example, args: [:foo]).result
...> defhook state_example(), do: call(:example, args: [nil], state: :foo).result
...> defhook config_example(), do: call(:example, args: [nil], config: :foo).result
...> defhook all_example(), do: call(:example, args: [:foo], state: :foo, config: :foo).result
...> end
iex> ExampleStrategy.arg_example(%Context{operation: ExampleOperation})
{:foo, nil, nil}
iex> ExampleStrategy.state_example(%Context{operation: ExampleOperation})
{nil, :foo, nil}
iex> ExampleStrategy.config_example(%Context{operation: ExampleOperation})
{nil, nil, :foo}
iex> ExampleStrategy.all_example(%Context{operation: ExampleOperation})
{:foo, :foo, :foo}
iex> ExampleStrategy.empty_example(%Context{operation: ExampleOperation})
** (UndefinedFunctionError) function Skitter.DSL.Strategy.HelpersTest.ExampleOperation.example/2 is undefined or private
Call callback
of the current operation if it exists.
Uses Skitter.Operation.call_if_exists/5
. The state, configuration and arguments can be passed
through opts (as in call/3
). If they are not provided, :args
defaults to the empty list
while :state
and :config
default to nil
.
Examples
iex> defoperation ExampleOperation, out: port do
...> defcb exists do
...> state <~ :exists
...> :exists ~> port
...> :exists
...> end
...> end
iex> defstrategy ExampleStrategy do
...> defhook exists_example(), do: call_if_exists(:exists)
...> defhook does_not_exist_example(), do: call_if_exists(:does_not_exist)
...> end
iex> ExampleStrategy.exists_example(%Context{operation: ExampleOperation})
%Result{result: :exists, state: :exists, emit: [port: [:exists]]}
iex> ExampleStrategy.does_not_exist_example(%Context{operation: ExampleOperation})
%Result{result: nil, state: nil, emit: []}
Emit data for the current context.
Raise a Skitter.StrategyError
The error is automatically annotated with the current context, which is used to retrieve the current operation and strategy.
Examples
iex> defstrategy Example do
...> defhook example, do: error("An error message")
...> end
iex> Example.example(%Context{strategy: Example, operation: Foo})
** (Skitter.StrategyError) Raised by Skitter.DSL.Strategy.HelpersTest.Example handling Foo:
An error message
Get the index of the given in port
.
Calls Skitter.Operation.in_port_to_index/2
.
Examples
iex> defoperation ExampleOperation, in: [foo, bar] do
...> end
iex> defstrategy ExampleStrategy do
...> defhook example(), do: in_port_to_index(:bar)
...> end
iex> ExampleStrategy.example(%Context{operation: ExampleOperation})
1
Get the name of the in port with the given index
.
Calls Skitter.Operation.index_to_in_port/2
.
Examples
iex> defoperation ExampleOperation, in: [foo, bar] do
...> end
iex> defstrategy ExampleStrategy do
...> defhook example(), do: index_to_in_port(1)
...> end
iex> ExampleStrategy.example(%Context{operation: ExampleOperation})
:bar
Get the name of the out port with the given index
.
Calls Skitter.Operation.index_to_out_port/2
.
Examples
iex> defoperation ExampleOperation, out: [foo, bar] do
...> end
iex> defstrategy ExampleStrategy do
...> defhook example(), do: index_to_out_port(0)
...> end
iex> ExampleStrategy.example(%Context{operation: ExampleOperation})
:foo
Create an empty state for the operation.
This macro creates an initial state for an operation, by using
Skitter.Operation.initial_state/2
Examples
iex> defoperation ExampleOperation do
...> initial_state :initial_state
...> end
iex> defstrategy ExampleStrategy do
...> defhook example(), do: initial_state()
...> end
iex> ExampleStrategy.example(%Context{operation: ExampleOperation})
:initial_state
Create a worker using Skitter.Worker.create_local/3
.
This macro creates a local worker, automatically passing the current context.
Get the index of the given out port
.
Calls Skitter.Operation.out_port_to_index/2
.
Examples
iex> defoperation ExampleOperation, out: [foo, bar] do
...> end
iex> defstrategy ExampleStrategy do
...> defhook example(), do: out_port_to_index(:foo)
...> end
iex> ExampleStrategy.example(%Context{operation: ExampleOperation})
0
Send a message to a worker using Elixir's Kernel.send/2
.
send/2
and send/3
defined in this module call Skitter.Worker.send/2
which will send a
message to a worker, eventually causing its Skitter.Strategy.Operation.process/4
hook to be
called.
In contrast, this function uses the built-in Kernel.send/2
of Elixir, which sends a message to
a pid. This is useful when you need to use Kernel.SpecialForms.receive/1
inside a hook.
Create a worker using Skitter.Worker.create_remote/4
.
This macro creates a remote worker, automatically passing the current context.
Send a message to a worker with Skitter.Worker.send/2
Stop the current worker using Skitter.Worker.stop/1
Stop the given worker using Skitter.Worker.stop/1
Programmatically create output for all out ports.
The data must be wrapped in a list.
Examples
iex> defoperation ExampleOperation, out: [foo, bar] do
...> end
iex> defstrategy ExampleStrategy do
...> defhook example(), do: to_all_ports([1, 2, 3])
...> end
iex> ExampleStrategy.example(%Context{operation: ExampleOperation})
[foo: [1, 2, 3], bar: [1, 2, 3]]
Programmatically create output for the out port with index
.
The data must be wrapped in a list.
Examples
iex> defoperation ExampleOperation, out: [foo, bar] do
...> end
iex> defstrategy ExampleStrategy do
...> defhook example(), do: to_port(0, [1, 2, 3])
...> end
iex> ExampleStrategy.example(%Context{operation: ExampleOperation})
[foo: [1, 2, 3]]