Jido.Exec (Jido v1.1.0-rc.2)
View SourceExec provides a robust set of methods for executing Actions (Jido.Action
).
This module offers functionality to:
- Run actions synchronously or asynchronously
- Manage timeouts and retries
- Cancel running actions
- Normalize and validate input parameters and context
- Emit telemetry events for monitoring and debugging
Execs are defined as modules (Actions) that implement specific callbacks, allowing for a standardized way of defining and executing complex actions across a distributed system.
Features
- Synchronous and asynchronous action execution
- Automatic retries with exponential backoff
- Timeout handling for long-running actions
- Parameter and context normalization
- Comprehensive error handling and reporting
- Telemetry integration for monitoring and tracing
- Cancellation of running actions
Usage
Execs are executed using the run/4
or run_async/4
functions:
Jido.Exec.run(MyAction, %{param1: "value"}, %{context_key: "context_value"})
See Jido.Action
for how to define an Action.
For asynchronous execution:
async_ref = Jido.Exec.run_async(MyAction, params, context)
# ... do other work ...
result = Jido.Exec.await(async_ref)
Summary
Functions
Waits for the result of an asynchronous Action execution.
Cancels a running asynchronous Action execution.
Executes a Action synchronously with the given parameters and context.
Executes a Action asynchronously with the given parameters and context.
Types
Functions
@spec await(async_ref(), timeout()) :: {:ok, map()} | {:error, Jido.Error.t()}
Waits for the result of an asynchronous Action execution.
Parameters
async_ref
: The reference returned byrun_async/4
.timeout
: Maximum time (in ms) to wait for the result (default: 5000).
Returns
{:ok, result}
if the Action executes successfully.{:error, reason}
if an error occurs during execution or if the action times out.
Examples
iex> async_ref = Jido.Exec.run_async(MyAction, %{input: "value"})
iex> Jido.Exec.await(async_ref, 10_000)
{:ok, %{result: "processed value"}}
iex> async_ref = Jido.Exec.run_async(SlowAction, %{input: "value"})
iex> Jido.Exec.await(async_ref, 100)
{:error, %Jido.Error{type: :timeout, message: "Async action timed out after 100ms"}}
@spec cancel(async_ref() | pid()) :: :ok | {:error, Jido.Error.t()}
Cancels a running asynchronous Action execution.
Parameters
async_ref
: The reference returned byrun_async/4
, or just the PID of the process to cancel.
Returns
:ok
if the cancellation was successful.{:error, reason}
if the cancellation failed or the input was invalid.
Examples
iex> async_ref = Jido.Exec.run_async(LongRunningAction, %{input: "value"})
iex> Jido.Exec.cancel(async_ref)
:ok
iex> Jido.Exec.cancel("invalid")
{:error, %Jido.Error{type: :invalid_async_ref, message: "Invalid async ref for cancellation"}}
Executes a Action synchronously with the given parameters and context.
Parameters
action
: The module implementing the Action behavior.params
: A map of input parameters for the Action.context
: A map providing additional context for the Action execution.opts
: Options controlling the execution::timeout
- Maximum time (in ms) allowed for the Action to complete (default: 5000).:max_retries
- Maximum number of retry attempts (default: 1).:backoff
- Initial backoff time in milliseconds, doubles with each retry (default: 250).:log_level
- Override the global Logger level for this specific action. Accepts [:error, :info, :debug, :emergency, :alert, :critical, :warning, :notice].
Action Metadata in Context
The action's metadata (name, description, category, tags, version, etc.) is made available
to the action's run/2
function via the context
parameter under the :action_metadata
key.
This allows actions to access their own metadata when needed.
Returns
{:ok, result}
if the Action executes successfully.{:error, reason}
if an error occurs during execution.
Examples
iex> Jido.Exec.run(MyAction, %{input: "value"}, %{user_id: 123})
{:ok, %{result: "processed value"}}
iex> Jido.Exec.run(MyAction, %{invalid: "input"}, %{}, timeout: 1000)
{:error, %Jido.Error{type: :validation_error, message: "Invalid input"}}
iex> Jido.Exec.run(MyAction, %{input: "value"}, %{}, log_level: :debug)
{:ok, %{result: "processed value"}}
# Access action metadata in the action:
# defmodule MyAction do
# use Jido.Action,
# name: "my_action",
# description: "Example action",
# vsn: "1.0.0"
#
# def run(_params, context) do
# metadata = context.action_metadata
# {:ok, %{name: metadata.name, version: metadata.vsn}}
# end
# end
Executes a Action asynchronously with the given parameters and context.
This function immediately returns a reference that can be used to await the result or cancel the action.
Note: This approach integrates with OTP by spawning tasks under a Task.Supervisor
.
Make sure {Task.Supervisor, name: Jido.Exec.TaskSupervisor}
is part of your supervision tree.
Parameters
action
: The module implementing the Action behavior.params
: A map of input parameters for the Action.context
: A map providing additional context for the Action execution.opts
: Options controlling the execution (same asrun/4
).
Returns
An async_ref
map containing:
:ref
- A unique reference for this async action.:pid
- The PID of the process executing the Action.
Examples
iex> async_ref = Jido.Exec.run_async(MyAction, %{input: "value"}, %{user_id: 123})
%{ref: #Reference<0.1234.5678>, pid: #PID<0.234.0>}
iex> result = Jido.Exec.await(async_ref)
{:ok, %{result: "processed value"}}