JasterV
Can't start a :gen_statem implementation under a registry
I have a :gen_statem implementation that I want to start via a registry like this:
defmodule Arca.PodImpl do
@moduledoc false
@behaviour :gen_statem
def start_link(opts) do
cell_ref = Keyword.get(opts, :cell_ref)
case cell_ref do
nil ->
{:error, "option 'cell_ref' is required to start the Pod"}
cell_ref ->
:gen_statem.start_link(__MODULE__, opts, name: via_registry(cell_ref))
end
end
end
defp via_registry(cell_ref) do
{:via, Registry, {Arca.Registry, {__MODULE__, cell_ref}}}
end
The first problem is that I can’t start this module under a supervision tree because :gen_statem doesn’t implement child_spec. So then I have to implement the child_spec myself:
# This is not automatically implemented by the gen_statem behaviour
def child_spec(opts) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [opts]}
}
end
So I end up with a module like this:
defmodule Arca.PodImpl do
@moduledoc false
def start_link(opts) do
cell_ref = Keyword.get(opts, :cell_ref)
case cell_ref do
nil ->
{:error, "option 'cell_ref' is required to start the Pod"}
cell_ref ->
:gen_statem.start_link(__MODULE__, opts, name: via_registry(cell_ref))
end
end
# This is not automatically implemented by the gen_statem behaviour
def child_spec(opts) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [opts]}
}
end
@impl true
def lock(ref), do: :gen_statem.cast(via_registry(ref), :lock)
@impl true
def unlock(ref), do: :gen_statem.cast(via_registry(ref), :unlock)
@impl true
def get_state(ref), do: :gen_statem.call(via_registry(ref), :get_state)
defp via_registry(cell_ref) do
{:via, Registry, {Arca.Registry, {__MODULE__, cell_ref}}}
end
end
For context, this is how I define my application children:
def children(_target, _env) do
[
{Registry, keys: :unique, name: Arca.Registry},
{Arca.PodImpl, cell_ref: "A1", lights_range: 75..95},
{Arca.PodImpl, cell_ref: "A2", lights_range: 61..73},
{Arca.PodImpl, cell_ref: "A3", lights_range: 20..58}
]
end
Now, the main problem is that the PodImpl process seems to not be registered on my registry.
So when I start my application, the PodImpl modules seem to be linked to the main supervisor (makes sense) but when I query the Registry there are no registered processes.
So when I try to call PodImpl.get_state("A1") it returns an error saying that there is no process with that name (the one constructed by the via_registry private function)
I hope someone can help me understand what is going on.
Marked As Solved
jswanner
The docs for start_link/3 state:
Equivalent to
start_link/4except that thegen_statemprocess is not registered with any name service.
I’m pretty sure you want:
:gen_statem.start_link(via_registry(cell_ref), __MODULE__, opts, [])
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








