Durable.Context (Durable v0.1.0-rc)
View SourceContext management for workflow execution.
The context is a key-value store that persists across steps within a workflow. It provides a way to share state between steps and is automatically persisted to the database after each step completes.
Usage
defmodule MyApp.OrderWorkflow do
use Durable
use Durable.Context
workflow "process_order" do
step :init do
order = input().order
put_context(:order_id, order.id)
put_context(:items, order.items)
end
step :calculate_total do
items = get_context(:items)
total = Enum.sum(Enum.map(items, & &1.price))
put_context(:total, total)
end
step :finalize do
%{
order_id: get_context(:order_id),
total: get_context(:total)
}
end
end
endContext Storage
During execution, context is stored in the process dictionary for fast access. After each step completes, the context is persisted to the database. When a workflow resumes (e.g., after a sleep or wait), the context is restored from the database.
Summary
Functions
Injects context management functions into the calling module.
Appends a value to a list in the context.
Returns the entire context map.
Returns the current step name.
Deletes a key from the context.
Gets a value from the context by key.
Gets a value from the context by key with a default.
Checks if a key exists in the context.
Increments a numeric value in the context.
Returns the initial workflow input.
Deep merges a map into the context.
Checks if a parallel step succeeded.
Returns a specific parallel step's result by name.
Returns the full parallel results map from context.
Merges a map into the context.
Puts a single key-value pair into the context.
Updates a context value using a function.
Returns the current workflow ID.
Functions
Injects context management functions into the calling module.
Appends a value to a list in the context.
If the key doesn't exist, creates a new list with the value.
Examples
append_context(:events, %{type: :clicked, timestamp: DateTime.utc_now()})
@spec context() :: map()
Returns the entire context map.
Examples
ctx = context()
# => %{order_id: 123, items: [...]}
@spec current_step() :: atom() | nil
Returns the current step name.
Examples
step = current_step()
Deletes a key from the context.
Examples
delete_context(:temporary_data)
delete_context("temporary_data")
Gets a value from the context by key.
Returns nil if the key doesn't exist.
Examples
order_id = get_context(:order_id)
Gets a value from the context by key with a default.
Examples
count = get_context(:retry_count, 0)
count = get_context("retry_count", 0)
Checks if a key exists in the context.
Examples
if has_context?(:order_id) do
# ...
end
Increments a numeric value in the context.
If the key doesn't exist, starts from 0.
Examples
increment_context(:retry_count, 1)
increment_context(:processed_items, 1)
@spec input() :: map()
Returns the initial workflow input.
Examples
order = input().order
@spec merge_context(map()) :: :ok
Deep merges a map into the context.
Examples
merge_context(%{settings: %{notifications: true}})
Checks if a parallel step succeeded.
Examples
step :handle, fn ctx ->
if parallel_ok?(:payment) do
# payment succeeded
else
# payment failed
end
end
Returns a specific parallel step's result by name.
Examples
step :handle, fn ctx ->
case parallel_result(:payment) do
{:ok, payment} -> # handle success
{:error, reason} -> # handle error
end
end
@spec parallel_results() :: map()
Returns the full parallel results map from context.
The results map contains tagged tuples: %{step_name => {:ok, data} | {:error, reason}}
Examples
parallel do
step :payment, fn ctx -> {:ok, %{id: 123}} end
step :delivery, fn ctx -> {:error, :not_found} end
end
step :handle, fn ctx ->
results = parallel_results()
# => %{payment: {:ok, %{id: 123}}, delivery: {:error, :not_found}}
end
@spec put_context(map()) :: :ok
Merges a map into the context.
Examples
put_context(%{order_id: 123, customer_id: 456})
Puts a single key-value pair into the context.
Examples
put_context(:order_id, 123)
put_context("order_id", 123)
Updates a context value using a function.
Examples
update_context(:retry_count, &(&1 + 1))
update_context(:items, &[new_item | &1])
@spec workflow_id() :: String.t() | nil
Returns the current workflow ID.
Examples
id = workflow_id()