Crank.Server (Crank v0.2.0)

Copy Markdown View Source

Runs a Crank callback module as a supervised gen_statem process.

The Server calls the same handle/3 or handle_event/4 functions that Crank.crank/2 calls. It adds what pure functions can't do: execute timeouts, send replies, emit telemetry on every transition, and integrate with OTP supervision.

Two ways to use it

Separate logic and server modules:

defmodule MyApp.DoorServer do
  use Crank.Server, logic: MyApp.Door
end

{:ok, pid} = Crank.Server.start_link(MyApp.DoorServer, [])
Crank.Server.cast(pid, :unlock)

Inline -- the logic module is the server module:

defmodule MyApp.Door do
  use Crank
  use Crank.Server

  @impl Crank
  def init(_opts), do: {:ok, :locked, %{}}

  @impl Crank
  def handle_event(_, :unlock, :locked, data), do: {:next_state, :unlocked, data}
  def handle_event(_, :lock, :unlocked, data), do: {:next_state, :locked, data}
end

Both produce a supervised process. The callback module doesn't change.

Summary

Types

Return value of start_link/3.

A pid, registered name, or {name, node} tuple identifying a running server.

Functions

Sends a synchronous event and waits for the server to reply.

Sends an asynchronous event to the server. Returns :ok immediately.

Starts a Crank.Server process linked to the calling process.

Types

on_start()

@type on_start() :: {:ok, pid()} | :ignore | {:error, term()}

Return value of start_link/3.

server()

@type server() :: GenServer.server()

A pid, registered name, or {name, node} tuple identifying a running server.

Functions

call(server, event, timeout \\ 5000)

@spec call(server(), event :: term(), timeout()) :: term()

Sends a synchronous event and waits for the server to reply.

The callback module replies using {:reply, from, response} in its effects list. Times out after timeout milliseconds (default 5000).

cast(server, event)

@spec cast(server(), event :: term()) :: :ok

Sends an asynchronous event to the server. Returns :ok immediately.

start_link(module, args, opts \\ [])

@spec start_link(module(), args :: term(), keyword()) :: on_start()

Starts a Crank.Server process linked to the calling process.

Crank calls module.init(args) to get the starting state and data. Pass :name in opts to register the process. All other options are forwarded to :gen_statem.start_link/3 (:debug, :spawn_opt, etc.).