View Source TPK.Common.OTP.RegisteredServer (tpk_common v0.0.1)
Defines a GenServer which can be addressed by a name instead a pid.
By using the module we will inject you a start_link/1
function and another
function reg_name/1
.
First make sure you have a Registry
up and running. Usually, in a Phoenix
or Elixir
application you will do that in Application
and start the Registry as a supervised
child, like so
application.ex
...
def start(_type, _args) do
children =
[
...,
{Registry,keys: :unique, name: MyRegistry}
]
...
Then define your own GenServer but use use RegisteredServer
instead of use GenServer
directely. When using RegisteredServer, provide two arguments. The module you're about
to define and the registry to use.
When calling start_link/1
you have to provide reg_name
as an argument for the unique
process name to be registered, followed by whatever keys your server needs.
{:ok, _unused_pid} = ServerTest.start_link(reg_name: "Server-1", my_key: :something)
example
Example
For your server you have to implement the init/1
function but not start_link/1
.
start_link/1
will be defined by use RegisteredServer
implicitly.
defmodule ServerTest do
use RegisteredServer, module: __MODULE__, registry: MyRegistry
@impl true
def init(args) do
{:ok, args}
end
def myfunc(server) do
GenServer.call(process_name(server), :mystate)
end
@impl true
def handle_call(:mystate, _, state), do: {:reply, state[:mystate], state}
end
usage
Usage
{:ok, _s1} = ServerTest.start_link(reg_name: "Server-1", mystate: :foo)
{:ok, _s2} = ServerTest.start_link(reg_name: "Server-2", mystate: :bar)
{:error, {:already_started, _pid}} = ServerTest.start_link(reg_name: "Server-2")
assert ServerTest.reg_name("Server-1") == "Server-1"
assert ServerTest.mystate("Server-1") == :foo
assert ServerTest.reg_name("Server-2") == "Server-2"
assert ServerTest.mystate("Server-2") == :bar