Working through the Supervisor and Application part of the Getting Started tutorial, I'm writing a unit test for the supervision tree problem at the bottom. I tried starting the top-level supervisor but it failed with this error:
1) test all buckets die if registry dies (KV.SupervisorTest)
test/kv/supervisor_test.exs:4
** (EXIT from #PID<0.111.0>) shutdown: failed to start child: GenEvent
** (EXIT) already started: #PID<0.75.0>
Apparently the app is already started, so I need to get access to its worker processes. I could use Supervisor.which_children to get them if I had the supervisor. To get that, maybe it would help to have the running kv
application:
iex(28)> kvpid = :application.info[:running][:kv]
#PID<0.77.0>
So now I have the PID for the app. Is there some way to get the root supervisor process from this, or do I have to manually register it somewhere to get at it from the test?
Or is there a way to directly get the workers from their names? I tried :erlang.whereis
but it doesn't find the worker:
iex(33)> :erlang.whereis KV.Registry
:undefined
I tried using the name of the module directly, but that doesn't work either:
test "all buckets die if registry dies" do
reg = KV.Registry
KV.Registry.create(reg, "shopping")
{:ok, shopping_bucket} = KV.Registry.lookup(reg, "shopping")
Process.exit(reg, :shutdown)
assert_receive {:exit, "shopping", ^shopping_bucket}
end
It fails with this error:
1) test all buckets die if registry dies (KV.SupervisorTest)
test/kv/supervisor_test.exs:4
** (ArgumentError) argument error
stacktrace:
:erlang.send(KV.Registry, {:"$gen_cast", {:create, "shopping"}})
(elixir) lib/gen_server.ex:424: GenServer.do_send/2
test/kv/supervisor_test.exs:6
The code is up on github.
You can't find KV.Registry because there's a typo in your code. You call:
worker(KV.Registry, [@manager_name, [name: @registry_name]])
but the definition is:
def start_link(event_manager, buckets_supervisor, opts \\ []) do
So you pass [name: KV.Registry] as buckets_supervisor, opts is [] and your worker is therefore not registered under the name KV.Registry.
Try this patch: https://github.com/mprymek/kv/commit/03ce2e4e5ab4287db2fab6de0bb1aeaf0226346f
iex(1)> :erlang.whereis KV.Registry
#PID<0.111.0>
If you start the supervisor given it a name, you can get all workers with:
Supervisor.which_children(MyApp.Supervisor)
What is likely happening is that you are trying to start two worker(GenEvent, ...)
and they will have duplicated events. Passing the :id
option explicitly will likely fix it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With