View Source FunServer (FunServer v0.1.4)

FunServer is a GenServer in which instead of passing parameters to GenServer.call/3 or GenServer.cast/2 and then writing the corresponding callbacks with the necessary functionality you pass functions (i.e. handlers).

Essentially FunServer is just a simple wrapper over GenServer, which takes the approach of passing down functions instead of messages.

example

Example

Basically instead of using init, handle_continue, handle_call or handle_cast callbacks, functions are being passed that get executed in the corresponding callback.

This is an example of a simple FunServer Stack Server.

defmodule Server do
  use FunServer

  def start_link(_args) do
    FunServer.start_link(__MODULE__, [name: __MODULE__], fn -> {:ok, args} end)
  end

  def push(value) do
    FunServer.async(__MODULE__, fn state ->
      {:noreply, [value | state]}
    end)
  end

  def pop(value) do
    FunServer.sync(__MODULE__, fn _from, [value | new_state] ->
      {:noreply, value, new_state}
    end)
  end
end

The callbacks FunServer wraps around are the following:

  • init/1
  • handle_call/3
  • handle_cast/2
  • handle_continue/2

The rest of the callbacks for GenServer can be handled normally:

  • handle_info/2
  • terminate/2
  • code_change/3
  • format_status/2

Link to this section Summary

Functions

Casts all servers locally registered as name at the specified nodes.

Executes an asynchronous call to the server. Works very similar to how a GenServer.cast/2 function works, but instead of passing message which is later handled in a handle_cast/2 callback, a function is passed, which gets evaluated on the server.

Calls all servers locally registered as name at the specified nodes.

Replies to a client.

Starts a FunServer process without links (outside of a supervision tree)

Starts a FunServer process linked to the current 'caller' process.

Synchronously stops the server with the given reason.

Executes a synchronous call to the server and waits for a reply. Works very similar to how a GenServer.call/3 function works, but instead of passing message which is later handled in a handle_call/3 callback, a function is passed, which gets evaluated on the server.

Link to this section Types

@type async_handler() ::
  mfa()
  | (state() ->
       {:noreply, new_state()}
       | {:noreply, new_state(),
          timeout() | :hibernate | {:continue, async_handler()}}
       | {:stop, reason(), new_state()})
@type init_handler() ::
  (() -> {:ok, state()}
         | {:ok, state(), timeout() | :hibernate | {:continue, async_handler()}}
         | :ignore
         | {:stop, reason()})
@type new_state() :: any()
@type reason() :: any()
@type reply() :: any()
@type state() :: any()
@type sync_handler() ::
  mfa()
  | (from :: GenServer.from(), state() ->
       {:reply, reply(), new_state()}
       | {:reply, reply(), new_state(),
          timeout() | :hibernate | {:continue, async_handler()}}
       | {:noreply, new_state()}
       | {:noreply, new_state(),
          timeout() | :hibernate | {:continue, async_handler()}}
       | {:stop, reason(), reply(), new_state()}
       | {:stop, reason(), new_state()})

Link to this section Functions

Link to this function

abcast(nodes \\ [node() | Node.list()], name, request)

View Source
@spec abcast(nodes :: [node()], name :: atom(), request :: any()) :: :abcast

Casts all servers locally registered as name at the specified nodes.

For more information please refer to GenServer.abcast/3

@spec async(GenServer.server(), async_handler()) :: any()

Executes an asynchronous call to the server. Works very similar to how a GenServer.cast/2 function works, but instead of passing message which is later handled in a handle_cast/2 callback, a function is passed, which gets evaluated on the server.

For additional information please refer to GenServer.cast/2

Link to this macro

is_server(server)

View Source (macro)
Link to this function

multi_call(nodes \\ [node() | Node.list()], name, request, timeout \\ :infinity)

View Source
@spec multi_call(
  nodes :: [node()],
  name :: atom(),
  request :: any(),
  timeout :: timeout()
) :: {replies :: [{node(), any()}], bad_nodes :: [node()]}

Calls all servers locally registered as name at the specified nodes.

For more information please refer to GenServer.multi_call/4

@spec reply(from :: GenServer.from(), reply :: any()) :: :ok

Replies to a client.

For more information please refer to GenServer.reply/2

Link to this function

start(module, options \\ [], init_handler)

View Source
@spec start(module(), GenServer.options(), init_handler()) ::
  {:ok, pid()} | {:error, any()} | :ignore

Starts a FunServer process without links (outside of a supervision tree)

For more information please refer to GenServer.start/3

example

Example

iex> FunServer.start(MyFunServer, [name: MyFunServer], fn -> {:ok, []} end)
Link to this function

start_link(module, options \\ [], init_handler)

View Source
@spec start_link(module(), GenServer.options(), init_handler()) ::
  {:ok, pid()} | {:error, any()} | :ignore

Starts a FunServer process linked to the current 'caller' process.

For more information please refer to GenServer.start_link/3

example

Example

iex> FunServer.start_link(MyFunServer, [name: MyFunServer], fn -> {:ok, []} end)
Link to this function

stop(server, reason \\ :normal, timeout \\ :infinity)

View Source
@spec stop(GenServer.server(), reason :: any(), timeout()) :: :ok

Synchronously stops the server with the given reason.

For more information please refer to GenServer.stop/3

Link to this function

sync(server, timeout \\ 5000, handler)

View Source
@spec sync(GenServer.server(), timeout(), sync_handler()) :: any()

Executes a synchronous call to the server and waits for a reply. Works very similar to how a GenServer.call/3 function works, but instead of passing message which is later handled in a handle_call/3 callback, a function is passed, which gets evaluated on the server.

For additional information please refer to GenServer.call/3