Journey.Tools (Journey v0.10.30)

This module contains utility functions for the Journey library.

Summary

Functions

Returns the current state of a computation node.

Converts a computation state atom to human-readable text with a visual symbol.

Shows the status and dependencies for a single computation node.

Generates a Mermaid diagram representation of a Journey graph.

Generates a human-readable text summary of an execution's current state.

Generates structured data about an execution's current state.

Generates a human-readable text summary of an execution's current state.

Shows the status of upstream dependencies for a computation node.

Functions

computation_state(execution_id, node_name)

Returns the current state of a computation node.

Returns the state of the most recent computation attempt for the given node. If no computation has been attempted yet, returns :not_set. For input nodes (non-compute nodes), returns :not_compute_node.

Parameters

  • execution_id - The ID of the execution to check
  • node_name - The atom name of the node to check

Returns

  • :not_set - No computation has been attempted yet
  • :computing - Currently computing
  • :success - Computation completed successfully
  • :failed - Computation failed
  • :abandoned - Computation was abandoned
  • :cancelled - Computation was cancelled
  • :not_compute_node - The node is an input node, not a computation

Examples

iex> import Journey.Node
iex> graph = Journey.new_graph("computation_state doctest graph", "v1.0.0", [
...>   input(:value),
...>   compute(:double, [:value], fn %{value: v} -> {:ok, v * 2} end)
...> ])
iex> execution = Journey.start_execution(graph)
iex> Journey.Tools.computation_state(execution.id, :double)
:not_set
iex> Journey.Tools.computation_state(execution.id, :value)
:not_compute_node
iex> execution = Journey.set_value(execution, :value, 5)
iex> {:ok, _result} = Journey.get_value(execution, :double, wait_new: true)
iex> Journey.Tools.computation_state(execution.id, :double)
:success

computation_state_to_text(state)

Converts a computation state atom to human-readable text with a visual symbol.

Returns a formatted string with an appropriate symbol and the state atom for each computation state, following the pattern used in other Journey text formatting functions.

Parameters

Returns

A string with symbol and the state atom.

State Representations

  • :not_set - "⬜ :not_set (not yet attempted)"
  • :computing - "⏳ :computing"
  • :success - "✅ :success"
  • :failed - "❌ :failed"
  • :abandoned - "❓ :abandoned"
  • :cancelled - "🛑 :cancelled"
  • :not_compute_node - "📝 :not_compute_node"

Examples

iex> Journey.Tools.computation_state_to_text(:success)
"✅ :success"

iex> Journey.Tools.computation_state_to_text(:computing)
"⏳ :computing"

iex> Journey.Tools.computation_state_to_text(:not_set)
"⬜ :not_set (not yet attempted)"

computation_status_as_text(execution_id, node_name)

Shows the status and dependencies for a single computation node.

Provides a focused view of one specific computation node's status and dependencies, similar to the computation sections in summarize_as_text/1 but for just one node.

Parameters

  • execution_id - The ID of the execution to analyze
  • node_name - The atom name of the computation node to check

Returns

A string showing the node's current status and dependencies.

For completed computations, shows the result with inputs used:

:send_follow_up (CMPTA5MDJHVXRMG54150EGX):  :success | :compute | rev 4
inputs used:
   :user_applied (rev 0)
   :card_mailed (rev 0)

For outstanding computations, shows the dependency tree:

:send_weekly_reminder (CMPTA5MDJHVXRMG54150EGX):  :not_set (not yet attempted) | :compute
     :and
       🛑 :subscribe_weekly | &true?/1
       🛑 :weekly_reminder_schedule | &provided?/1
        :email_address | &provided?/1 | rev 2

For input nodes (non-compute nodes), returns an appropriate message.

Examples

iex> import Journey.Node
iex> graph = Journey.new_graph("computation_status_as_text doctest", "v1.0.0", [
...>   input(:value),
...>   compute(:double, [:value], fn %{value: v} -> {:ok, v * 2} end)
...> ])
iex> execution = Journey.start_execution(graph)
iex> Journey.Tools.computation_status_as_text(execution.id, :double)
":double: ⬜ :not_set (not yet attempted) | :compute\n       ✅ :value | &is_set/1"

iex> import Journey.Node
iex> graph = Journey.new_graph("computation_status_as_text completed doctest", "v1.0.0", [
...>   input(:value),
...>   compute(:triple, [:value], fn %{value: v} -> {:ok, v * 3} end)
...> ])
iex> execution = Journey.start_execution(graph)
iex> execution = Journey.set_value(execution, :value, 5)
iex> {:ok, _} = Journey.get_value(execution, :triple, wait_new: true)
iex> result = Journey.Tools.computation_status_as_text(execution.id, :triple)
iex> result =~ ":triple"
true
iex> result =~ "✅ :success"
true
iex> result =~ "inputs used"
true

generate_mermaid_graph(graph, opts \\ [])

Generates a Mermaid diagram representation of a Journey graph.

Converts a graph into Mermaid syntax for visualization. By default returns only the flow diagram without legend or timestamp.

Quick Example

# Just the flow
mermaid = Journey.Tools.generate_mermaid_graph(graph)

# Include legend and timestamp
mermaid = Journey.Tools.generate_mermaid_graph(graph,
  include_legend: true,
  include_timestamp: true
)

Options

  • :include_legend - Include node type legend (default: false)
  • :include_timestamp - Include generation timestamp (default: false)

retry_computation(execution_id, computation_node_name)

Retries a failed computation.

This function enables retrying computations that have exhausted their max_retries by making their previous attempts "stale" through upstream revision changes, then creating a new computation for the scheduler to pick up.

Parameters

  • execution_id - The ID of the execution containing the failed computation
  • computation_node_name - The atom name of the computation node to retry

Returns

The updated execution struct

Example

iex> Journey.Tools.retry_computation("EXEC123", :email_horoscope)
%Journey.Persistence.Schema.Execution{...}

How It Works

  1. Finds upstream dependencies that are currently satisfied
  2. Increments the revision of the first available upstream node
  3. Creates a new :not_set computation for the scheduler to pick up
  4. Previous failed attempts become "stale" in the retry counting logic
  5. The scheduler can now execute the new computation attempt

summarize(execution_id)

This function is deprecated. Use summarize_as_text/1 instead.

Generates a human-readable text summary of an execution's current state.

This function is deprecated. Use summarize_as_text/1 instead.

Parameters

  • execution_id - The ID of the execution to analyze

Returns

A formatted string with the complete execution state summary.

summarize_as_data(execution_id)

Generates structured data about an execution's current state.

Returns a map containing:

  • Execution metadata (ID, graph, timestamps, duration, revision, archived status)
  • Values categorized as set/not_set with their details
  • Computations categorized as completed/outstanding with dependency info

Example

iex> Journey.Tools.summarize_as_data("EXEC07B2H0H7J1LTAE0VJDAL")
%{
  execution_id: "EXEC07B2H0H7J1LTAE0VJDAL",
  graph_name: "g1",
  graph_version: "v1",
  archived_at: nil,
  created_at: 1723656196,
  updated_at: 1723656210,
  duration_seconds: 14,
  revision: 7,
  values: %{
    set: [...],
    not_set: [...]
  },
  computations: %{
    completed: [...],
    outstanding: [...]
  }
}

Parameters

  • execution_id - The ID of the execution to analyze

Returns

A structured map with execution state data.

Use summarize_as_text/1 to get execution summary as text.

summarize_as_text(execution_id)

Generates a human-readable text summary of an execution's current state.

Example

iex> Journey.Tools.summarize_as_text("EXEC07B2H0H7J1LTAE0VJDAL") |> IO.puts()
Execution summary:
- ID: 'EXEC07B2H0H7J1LTAE0VJDAL'
- Graph: 'g1' | 'v1'
...
:ok

Parameters

  • execution_id - The ID of the execution to analyze

Returns

A formatted string with the complete execution state summary.

Use summarize_as_data/1 to get execution summary as data.

what_am_i_waiting_for(execution_id, computation_node_name)

Shows the status of upstream dependencies for a computation node.

Lists each dependency with a checkmark (✅) if satisfied or a stop sign (🛑) if not. Useful for debugging to see which dependencies are met and which are still blocking.

Parameters

  • execution_id - The ID of the execution to analyze
  • computation_node_name - The atom name of the computation node to check

Returns

A string showing the readiness status with checkmarks for met conditions and stop signs for unmet conditions.

Example

iex> import Journey.Node
iex> graph = Journey.new_graph("what_am_i_waiting_for test graph Elixir.Journey.Tools", "v1.0.0", [
...>   input(:name),
...>   input(:title),
...>   compute(:greeting, [:name, :title], fn %{name: name, title: title} ->
...>     {:ok, "Hello, #{title} #{name}!"}
...>   end)
...> ])
iex> {:ok, execution} = Journey.start_execution(graph)
iex> Journey.Tools.what_am_i_waiting_for(execution.id, :greeting) |> IO.puts()
🛑 :name | &is_set/1
🛑 :title | &is_set/1
:ok
iex> {:ok, execution} = Journey.set_value(execution, :name, "Alice")
iex> Journey.Tools.what_am_i_waiting_for(execution.id, :greeting) |> IO.puts()
 :name | &is_set/1 | rev 1
🛑 :title | &is_set/1
:ok
iex> {:ok, execution} = Journey.set_value(execution, :title, "Dr.")
iex> {:ok, _greeting_value} = Journey.get_value(execution, :greeting, wait_new: true)
iex> Journey.Tools.what_am_i_waiting_for(execution.id, :greeting) |> IO.puts()
 :name | &is_set/1 | rev 1
 :title | &is_set/1 | rev 2
:ok