Jido.Persist (Jido v2.0.0)

View Source

Coordinates hibernate/thaw operations for agents with thread support.

This module is the invariant enforcer - it ensures:

  1. Journal is flushed before checkpoint
  2. Checkpoint never contains full Thread, only a pointer
  3. Thread is rehydrated on thaw

API

The primary API accepts a storage configuration tuple:

Jido.Persist.hibernate({adapter, opts}, agent)
Jido.Persist.hibernate({adapter, opts}, agent_module, key, agent)
Jido.Persist.thaw({adapter, opts}, agent_module, key)

Or a Jido instance with embedded storage config:

Jido.Persist.hibernate(jido_instance, agent)
Jido.Persist.hibernate(jido_instance, agent_module, key, agent)
Jido.Persist.thaw(jido_instance, agent_module, key)

hibernate Flow

  1. Extract thread from agent.state[:__thread__]
  2. Flush only missing thread entries via adapter.append_thread/3
  3. Call agent_module.checkpoint/2 if implemented, else use default
  4. Enforce invariant: Remove :__thread__ from state, store only thread pointer
  5. Call adapter.put_checkpoint/3

thaw/3 Flow

  1. Call adapter.get_checkpoint/2
  2. If missing, return {:error, :not_found}
  3. Call agent_module.restore/2 if implemented, else use default
  4. If checkpoint has thread pointer, load and attach thread
  5. Verify loaded thread.rev matches checkpoint pointer rev

Agent Callbacks

Agents may optionally implement:

  • checkpoint(agent, ctx) - Returns {:ok, checkpoint_data} for custom serialization
  • restore(checkpoint_data, ctx) - Returns {:ok, agent} for custom deserialization

If not implemented, default serialization is used.

Summary

Functions

Persists an agent to storage, flushing any pending thread entries first.

Persists an agent using an explicit {agent_module, key} identity.

Restores an agent from storage, rehydrating thread if present.

Types

agent()

@type agent() :: struct()

agent_module()

@type agent_module() :: module()

checkpoint()

@type checkpoint() :: %{
  version: pos_integer(),
  agent_module: agent_module(),
  id: term(),
  state: map(),
  thread: thread_pointer() | nil
}

checkpoint_key()

@type checkpoint_key() :: {agent_module(), term()}

key()

@type key() :: term()

storage_config()

@type storage_config() :: {module(), keyword()}

thread_pointer()

@type thread_pointer() :: %{id: String.t(), rev: non_neg_integer()}

Functions

hibernate(storage_or_instance, agent)

@spec hibernate(storage_config() | module() | struct(), agent()) ::
  :ok | {:error, term()}

Persists an agent to storage, flushing any pending thread entries first.

Accepts a {storage_adapter, opts} tuple, a storage adapter module, a map/struct with :storage, or a Jido instance module.

hibernate(storage_or_instance, agent_module, key, agent)

@spec hibernate(
  storage_config() | module() | struct(),
  agent_module(),
  key(),
  agent()
) ::
  :ok | {:error, term()}

Persists an agent using an explicit {agent_module, key} identity.

This is primarily used by keyed lifecycle managers that persist with pool keys.

thaw(storage_or_instance, agent_module, key)

@spec thaw(storage_config() | module() | struct(), agent_module(), key()) ::
  {:ok, agent()} | {:error, term()}

Restores an agent from storage, rehydrating thread if present.

Accepts a {storage_adapter, opts} tuple, a storage adapter module, a map/struct with :storage, or a Jido instance module.