Packages
gen_server_proxy
0.1.35
0.1.72
0.1.71
0.1.70
0.1.68
0.1.67
0.1.66
0.1.65
0.1.64
0.1.63
0.1.62
0.1.61
0.1.60
0.1.59
0.1.58
0.1.57
0.1.56
0.1.55
0.1.54
0.1.53
0.1.52
0.1.51
0.1.50
0.1.49
0.1.48
0.1.47
0.1.46
0.1.45
0.1.44
0.1.43
0.1.42
0.1.40
0.1.39
0.1.38
0.1.37
0.1.36
0.1.35
0.1.34
0.1.33
0.1.32
0.1.31
0.1.30
0.1.29
0.1.28
0.1.27
0.1.26
0.1.25
0.1.24
0.1.23
0.1.22
0.1.21
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Invokes call, cast or stop with a GenServer registered via a server ID. Will wait a bit if the GenServer is not yet registered on restarts.
Current section
Files
Jump to
Current section
Files
lib/gen_server/proxy.ex
defmodule GenServer.Proxy do
@moduledoc """
Invokes the following functions for a GenServer registered via a server ID:
- `GenServer.call/3`
- `GenServer.cast/2`
- `GenServer.stop/3`
Will wait a bit if the GenServer is not yet registered on restarts.
"""
@typedoc "Server ID"
@type server_id :: term
@doc """
Called to convert the `server_id` into a server name.
## Examples
@impl GenServer.Proxy
def server_name(game_name),
do: {:via, Registry, {:registry, game_name}}
@impl GenServer.Proxy
def server_name(game_name),
do: {:global, {GameServer, game_name}}
"""
@callback server_name(server_id) :: GenServer.name()
@doc ~S'''
Called when the server remains unregistered despite waiting a bit.
## Examples
@impl GenServer.Proxy
def server_unregistered(game_name),
do: :ok = IO.puts("Game #{game_name} not started.")
'''
@callback server_unregistered(server_id) :: term
@doc """
Either aliases `GenServer.Proxy` (this module) and requires the alias or
imports `GenServer.Proxy`. In the latter case, you could instead simply
`import GenServer.Proxy`.
## Examples
use GenServer.Proxy, alias: Proxy
use GenServer.Proxy
import GenServer.Proxy
"""
defmacro __using__(options) do
alias = options[:alias]
if alias do
quote do
alias unquote(__MODULE__), as: unquote(alias)
require unquote(alias)
end
else
quote do
import unquote(__MODULE__)
end
end
end
@doc ~S'''
Makes a synchronous call to the GenServer registered via `server_id`.
Will wait a bit if the GenServer is not yet registered on restarts.
The given `module` (or by default `<caller's_module>.GenServerProxy`) must
implement the 2 callbacks of `GenServer.Proxy` (this module).
## Examples
# Assuming the following callback module:
defmodule Game.Engine.GenServerProxy do
@behaviour GenServer.Proxy
@impl GenServer.Proxy
def server_name(game_name),
do: {:via, Registry, {:registry, game_name}}
@impl GenServer.Proxy
def server_unregistered(game_name),
do: :ok = IO.puts("Game #{game_name} not started.")
end
# We could use the call macro like so:
defmodule Game.Engine do
use GenServer.Proxy
def summary(game_name), do: call(game_name, :summary)
...
end
'''
defmacro call(server_id, request, timeout \\ 5000, module \\ nil) do
if module do
quote bind_quoted: [
server_id: server_id,
request: request,
timeout: timeout,
module: module
] do
GenServer.Proxy.Caller.call(server_id, request, timeout, module)
end
else
quote bind_quoted: [
server_id: server_id,
request: request,
timeout: timeout
] do
GenServer.Proxy.Caller.call(
server_id,
request,
timeout,
__MODULE__.GenServerProxy
)
end
end
end
@doc """
Sends an async request to the GenServer registered via `server_id`.
Will wait a bit if the GenServer is not yet registered on restarts.
The given `module` (or by default `<caller's_module>.GenServerProxy`) must
implement the 2 callbacks of `GenServer.Proxy` (this module).
"""
defmacro cast(server_id, request, module \\ nil) do
if module do
quote bind_quoted: [
server_id: server_id,
request: request,
module: module
] do
GenServer.Proxy.Caster.cast(server_id, request, module)
end
else
quote bind_quoted: [server_id: server_id, request: request] do
GenServer.Proxy.Caster.cast(
server_id,
request,
__MODULE__.GenServerProxy
)
end
end
end
@doc """
Synchronously stops the GenServer registered via `server_id`.
Will wait a bit if the GenServer is not yet registered on restarts.
The given `module` (or by default `<caller's_module>.GenServerProxy`) must
implement the 2 callbacks of `GenServer.Proxy` (this module).
"""
defmacro stop(
server_id,
reason \\ :normal,
timeout \\ :infinity,
module \\ nil
) do
if module do
quote bind_quoted: [
server_id: server_id,
reason: reason,
timeout: timeout,
module: module
] do
GenServer.Proxy.Stopper.stop(server_id, reason, timeout, module)
end
else
quote bind_quoted: [
server_id: server_id,
reason: reason,
timeout: timeout
] do
GenServer.Proxy.Stopper.stop(
server_id,
reason,
timeout,
__MODULE__.GenServerProxy
)
end
end
end
end