Anoma.Node.Transaction.Shard.Supervisor (Anoma v0.35.0)

I am the dynamic supervisor for Anoma.Node.Transaction.Shard processes.

I start with no children. Children (shards) are started dynamically either during initial node setup based on a provided schema or later via the start_shard/3 function. I maintain a Mnesia table (Anoma.Tables.table_shard_key_map/1) mapping keys to the registered name ({:via, Registry, {Anoma.Node, {Shard, key}}}) of the Shard process responsible for that key. The actual lookup of keys is handled by the Anoma.Node.Transaction.Ordering.

Key Concepts

  • Supervisor Args: Keyword list including :node_id, and optionally :strategy and :schema for initial setup.
  • Strategy: Determines how initial shards are created (e.g., :one_per_key). Only used during initial setup.
  • Schema: Defines the initial keys and their starting values. Only used during initial setup.
  • Mnesia Table: table_shard_key_map/1 for key -> shard name lookup (used by Anoma.Node.Transaction.Ordering).
  • Dynamic Starting: Use start_shard/3 to add new shards after initial setup.

Public API

  • start_link/1: I start the supervisor.
  • start_shard/3: I dynamically start a new shard for a given key and optionally value.
  • get_shard_key_map/1: I return the name of the Mnesia table for the shard key map for the given node ID.

Summary

Types

I am the type of the arguments that the ShardSupervisor expects at startup. I require :node_id and optionally :strategy and :schema keys for initial setup.

I represent the initial value associated with a key in a shard.

I represent a key managed by a shard.

I am the schema defining the keys and their initial values for shards. For the :one_per_key strategy, I expect a list containing either key binaries or {key, initial_value} tuples. If only a key is provided, there is no initial value.

I am the type of the arguments that the Shard process expects. I am not explicitly used, but this may be useful to know.

I am the sharding strategy. Currently, I only support :one_per_key.

Functions

Returns a specification to start this module under a supervisor.

I return the Mnesia table name for the shard key map for the given node ID.

I am the DynamicSupervisor initialization callback.

I am the start_link function for the ShardSupervisor.

I dynamically start a new shard process for the given key.

Types

args_t()

@type args_t() :: [
  node_id: String.t(),
  strategy: strategy() | nil,
  schema: schema() | nil
]

I am the type of the arguments that the ShardSupervisor expects at startup. I require :node_id and optionally :strategy and :schema keys for initial setup.

initial_value()

@type initial_value() :: any()

I represent the initial value associated with a key in a shard.

key()

@type key() :: [binary()]

I represent a key managed by a shard.

schema()

@type schema() :: [key() | {key(), initial_value()}]

I am the schema defining the keys and their initial values for shards. For the :one_per_key strategy, I expect a list containing either key binaries or {key, initial_value} tuples. If only a key is provided, there is no initial value.

shard_args()

@type shard_args() :: [id: key(), initial_kv: %{required(key()) => initial_value()}]

I am the type of the arguments that the Shard process expects. I am not explicitly used, but this may be useful to know.

strategy()

@type strategy() :: :one_per_key

I am the sharding strategy. Currently, I only support :one_per_key.

Functions

child_spec(arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

get_shard_key_map(node_id)

@spec get_shard_key_map(node_id :: String.t()) :: atom()

I return the Mnesia table name for the shard key map for the given node ID.

init(args)

@spec init(args :: [{:node_id, String.t()}]) :: {:ok, DynamicSupervisor.sup_flags()}

I am the DynamicSupervisor initialization callback.

I just set the process label and initialize the supervisor state. Initial child starting is handled in start_link/1 after this process starts.

start_link(args)

@spec start_link(args_t()) :: Supervisor.on_start()

I am the start_link function for the ShardSupervisor.

I start and link the dynamic supervisor process under the current supervision tree, registering myself locally using a node-specific name.

If initial :strategy and :schema are provided, I perform Mnesia setup synchronously before starting the supervisor. If Mnesia fails, I return an error. After the supervisor starts, I start the initial children.

start_shard(node_id, key, initial_value \\ nil)

@spec start_shard(
  node_id :: String.t(),
  key :: key(),
  initial_value :: initial_value() | nil
) :: DynamicSupervisor.on_start_child() | {:error, :mnesia_update_failed, any()}

I dynamically start a new shard process for the given key.

I register the shard with the registry and add its key mapping to the Mnesia table.