Recipe
Erlang OTP primer
OTP is the battle-tested framework that turns Erlang from a curious functional language into a platform for systems that run for nine nines. This primer walks through the three primitives you will use every day: supervisors, gen_servers, and applications. By the end you will understand how Meridian uses these patterns under the hood for resilient agent workers.
1. The supervision tree
Every OTP system starts with a supervisor. A supervisor is a process whose only job is to start, monitor, and restart its children according to a declared strategy. The four strategies are one_for_one, one_for_all, rest_for_one, and simple_one_for_one. Pick the weakest coupling your invariants tolerate.
2. The gen_server behaviour
A gen_server is a stateful server process with a uniform message protocol. You implement six callbacks and the framework handles mailboxes, selective receive, and OTP-compliant shutdowns. The pattern below shows the minimum surface area: a single synchronous call that increments a counter and returns the new value to the caller.
% Define a gen_server worker
-module(meridian_worker).
-behaviour(gen_server).
-export([start_link/0, ping/1]).
-export([init/1, handle_call/3, handle_cast/2]).
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
ping(Pid) ->
gen_server:call(Pid, ping).
init([]) ->
{ok, #{count => 0}}.
handle_call(ping, _From, State = #{count := N}) ->
{reply, {pong, N}, State#{count => N + 1}};
handle_call(_Msg, _From, State) ->
{reply, ignored, State}.
handle_cast(_Msg, State) ->
{noreply, State}.3. Releases and applications
An application bundles a supervision tree with metadata so the runtime can start it on boot and stop it on shutdown. A release packages one or more applications with a specific Erlang runtime into a tarball you ship to production. Hot code loading lets you upgrade modules in a running release without dropping connections, which is how Meridian rolls out worker upgrades to long-lived agent sessions.