SagaWeaver.Adapters.StorageAdapter behaviour (saga_weaver v0.2.0)

The SagaWeaver.Adapters.StorageAdapter module defines the behaviour and provides an interface for storage adapters used by the SagaWeaver framework.

Overview

SagaWeaver allows for pluggable storage backends to persist saga state and context. This module specifies the required callbacks that any storage adapter must implement to integrate with the framework. By abstracting the storage layer, SagaWeaver can support different storage systems like Redis, PostgreSQL, or custom solutions.

Responsibilities

  • Define Behaviour: Specifies the set of functions (callbacks) that a storage adapter must implement.
  • Delegation: Provides default implementations that delegate function calls to the configured storage adapter module.

Callbacks

Storage adapters must implement the following callbacks:

Usage

Developers can implement custom storage adapters by creating a module that implements this behaviour. The custom adapter must be configured in the application configuration.

Example Implementation

defmodule MyApp.CustomStorageAdapter do
  @behaviour SagaWeaver.Adapters.StorageAdapter

  alias SagaWeaver.SagaSchema

  @impl true
  def initialize_saga(saga_schema) do
    # Custom logic to initialize and store the saga
  end

  @impl true
  def saga_exists?(key) do
    # Custom logic to check if the saga exists
  end

  # Implement other callbacks...
end

Configuration

To use a custom storage adapter, set it in your application's configuration:

config :saga_weaver, :storage_adapter, MyApp.CustomStorageAdapter

The impl/0 function in SagaWeaver.Adapters.StorageAdapter retrieves the configured adapter and delegates the function calls.

Default Implementation

By default, SagaWeaver may provide built-in adapters like RedisAdapter or PostgresAdapter. If none is configured, you need to specify one to enable saga persistence.

Summary

Callbacks

Link to this callback

assign_context(t, map)

@callback assign_context(SagaWeaver.SagaSchema.t(), map()) ::
  {:ok, SagaWeaver.SagaSchema.t()}
Link to this callback

assign_state(t, map)

@callback assign_state(SagaWeaver.SagaSchema.t(), map()) ::
  {:ok, SagaWeaver.SagaSchema.t()}
Link to this callback

complete_saga(t)

@callback complete_saga(SagaWeaver.SagaSchema.t()) :: :ok
@callback get_saga(String.t()) :: {:ok, SagaWeaver.SagaSchema.t()} | {:ok, :not_found}
Link to this callback

initialize_saga(t)

@callback initialize_saga(SagaWeaver.SagaSchema.t()) ::
  {:ok, SagaWeaver.SagaSchema.t()} | {:error, Ecto.Changeset.t()}
Link to this callback

mark_as_completed(t)

@callback mark_as_completed(SagaWeaver.SagaSchema.t()) :: {:ok, SagaWeaver.SagaSchema.t()}
Link to this callback

saga_exists?(t)

@callback saga_exists?(String.t()) :: boolean()

Functions

Link to this function

assign_context(saga_schema, context)

@spec assign_context(SagaWeaver.SagaSchema.t(), map()) ::
  {:ok, SagaWeaver.SagaSchema.t()}
Link to this function

assign_state(saga_schema, state)

@spec assign_state(SagaWeaver.SagaSchema.t(), map()) ::
  {:ok, SagaWeaver.SagaSchema.t()}
Link to this function

complete_saga(saga_schema)

@spec complete_saga(SagaWeaver.SagaSchema.t()) :: :ok
@spec get_saga(String.t()) :: {:ok, SagaWeaver.SagaSchema.t()} | {:ok, :not_found}
Link to this function

initialize_saga(saga_schema)

@spec initialize_saga(SagaWeaver.SagaSchema.t()) ::
  {:ok, SagaWeaver.SagaSchema.t()} | {:error, Ecto.Changeset.t()}
Link to this function

mark_as_completed(saga_schema)

@spec mark_as_completed(SagaWeaver.SagaSchema.t()) :: {:ok, SagaWeaver.SagaSchema.t()}
Link to this function

saga_exists?(key)

@spec saga_exists?(any()) :: boolean()