Ramal.Supervisor (Ramal v0.2.0)

Copy Markdown View Source

The supervision tree of Ramal. Add it to the host application's tree:

children = [
  MyApp.Repo,
  {Ramal.Supervisor, storage: Ramal.Storage.Postgres, repo: MyApp.Repo}
]

It starts a Registry keyed by branch id, a DynamicSupervisor for the branch processes, and owns the ETS tables the library needs. There is one instance per node; its configuration lives in :persistent_term.

Options

  • :storage - a Ramal.Storage module, default Ramal.Storage.ETS
  • :idle_timeout - milliseconds without a call before a branch persists and unloads, default five minutes
  • :max_active_branches - the most open and proposed branches one domain may have, default nil (no limit). Ramal.branch/2 and Ramal.fork/2 return {:error, %Ramal.Error{reason: :limit_reached}} at the limit. A soft limit: callers that create at the same moment can pass it by their own number. Counting asks the storage for a count (Ramal.Storage.count/3), so it costs one query with Ramal.Storage.Postgres.
  • :branch_rate - {count, milliseconds}: the most branches (created or forked) one domain may get in a window, default nil. Fixed windows, counted in memory on this node, and shared by branch/2 and fork/2. Nodes do not add up: a cluster allows the rate on each node.
  • :max_heap_size - the heap limit of each branch process in words, default 25 million (200 MB on a 64-bit machine). A branch exceeding it is killed and its last persisted state remains.
  • any other option is the storage config, for example :repo for the Postgres backend

Both limits are off by default, so adding them is the only change; see ADR 0016 for why they exist (a client that can reach Ramal.fork/2, such as the inspector, can otherwise start a process and a stored row per call).

idle_timeout and max_heap_size belong to the supervisor, not to a branch, because a per-branch value would be forgotten when the branch is unloaded and loaded again.

Example

iex> opts = [storage: Ramal.Storage.ETS, idle_timeout: 1_000, repo: MyApp.Repo]
iex> config = Ramal.Supervisor.build_config(opts)
iex> {config.storage, config.idle_timeout, config.storage_config}
{Ramal.Storage.ETS, 1000, [repo: MyApp.Repo]}

Summary

Functions

Builds the runtime config from the supervisor options.

Returns a specification to start this module under a supervisor.

Types

config()

@type config() :: %{
  storage: module(),
  storage_config: keyword(),
  idle_timeout: timeout(),
  max_heap_size: pos_integer(),
  limits: %{
    max_active: pos_integer() | nil,
    rate: {pos_integer(), pos_integer()} | nil
  }
}

Functions

build_config(opts)

@spec build_config(keyword()) :: config()

Builds the runtime config from the supervisor options.

Example

iex> Ramal.Supervisor.build_config([]).idle_timeout
300000

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.