OTP GenServer

Minimal descriptive example of an OTP GenServer in Elixir.


defmodule Crawler.Explorer do
  use GenServer

  ## Client API

  @doc """
  Starts the process.
  """
  def start_link(opts) do
    GenServer.start_link(__MODULE__, :ok, opts)
  end

  @doc """
  execute a synchronous call to get data from the server
  """
  def lookup(server, name) do
    GenServer.call(server, {:lookup, name})
  end

  @doc """
  dispatch an asynchronous call to the server, will not wait for any response
  """
  def create(server, name) do
    GenServer.cast(server, {:create, name})
  end

  ## Server Callbacks

  @doc """
  Will be called from `GenServer.start_link/1`
  """
  def init(:ok) do
    initial_data = %{}
    {:ok, initial_data}
  end

  @doc """
  The Client will wait blocked until the call succeeds, applying backpressure
  """
  def handle_call({:lookup, name}, _from, data) do
    {:reply, Map.fetch(data, name), data}
  end

  @doc """
  The Client will **not** wait until the call succeeds, fire-and-forget
  """
  def handle_cast({:create, name}, data) do
    if Map.has_key?(data, name) do
      {:noreply, data}
    else
      {:noreply, Map.put(data, name, "new value")}
    end
  end
end

Implements a simple Map lookup with the common functions and callbacks. Should always be started from an OTP Supervisor.

Linked Technologies

What it's made of

illustration of Elixir
Elixir

Harness the power of concurrent, fault-tolerant programming for scalable, maintainable applications. Code that flows like water!

Linked Categories

Where it's useful

illustration of Software Architecture
Software Architecture

Dive into the world of Software Architecture where design meets functionality. Explore frameworks, patterns, and best practices that define the structure of software systems, making them robust, scalable, and maintainable.