defmodule FooRegistryConfig do
defstruct uuid: String.to_atom("#{__MODULE__}.#{UUID.uuid1(:hex)}")
end
defmodule FooRegistry do
use GenServer
def start_link do
Logger.log(:info, "Starting FooRegistry...")
GenServer.start_link(__MODULE__, [], [{:name, __MODULE__}])
end
def init(_opts \\ []) do
Logger.log(:debug, "#{__MODULE__} initializing")
config = %FooRegistryConfig{}
{:ok, config}
end
def handle_call({command, msg}, _from, config) do
Logger.log(:debug, "Received #{msg}")
case command do
# Foo with pid <_from> needs Foo in <msg>
:needs ->
needs_foo(_from, msg)
end
{:reply, :ok, config}
end
defp needs_foo({foo_pid, _}, needed_foo) do
Logger.log(:debug, "Foo needs #{needed_foo}")
import Supervisor.Spec
Supervisor.start_child(FooSupervisor, worker(needed_foo, [], [restart: :permanent]))
end
end
defmodule BaseFoo do
use GenServer
def start_link do
Logger.log(:info, "Starting BaseFoo...")
GenServer.start_link(__MODULE__, [], [{:name, __MODULE__}])
end
def init(_opts \\ []) do
Logger.log(:debug, "#{__MODULE__} initializing")
config = %BaseFooConfig{}
{:ok, config}
end
...
end
and finally the SampleFoo:
defmodule SampleFooConfig do
defstruct uuid: String.to_atom("#{__MODULE__}.#{UUID.uuid1(:hex)}")
end
defmodule SampleFoo do
use GenServer
@moduledoc false
def start_link do
Logger.log(:info, "Starting SampleFoo...")
GenServer.start_link(__MODULE__, [], [{:name, __MODULE__}])
end
def init(_opts \\ []) do
Logger.log(:debug, "#{__MODULE__} initializing")
config = %SampleFooConfig{}
GenServer.call(FooRegistry, {:needs, BaseFoo}, 500)
{:ok, config}
end
def handle_call(_msg, _from, config) do
Logger.log(:debug, "SampleFoo: Received #{_msg}")
{:reply, :ok, config}
end
....
end
So if I launch this code, the output says:
2015-09-16 14:59:51.349 [info] Starting FooTest...
2015-09-16 14:59:51.349 [info] Supervisor: starting...
2015-09-16 14:59:51.349 [debug] Supervisor: launching children...
2015-09-16 14:59:51.349 [info] Starting FooRegistry...
2015-09-16 14:59:51.349 [debug] Elixir.FooRegistry initializing
2015-09-16 14:59:51.349 [info] Starting SampleFoo...
2015-09-16 14:59:51.349 [debug] Elixir.SampleFoo initializing
2015-09-16 14:59:51.349 [debug] Received Elixir.BaseFoo
2015-09-16 14:59:51.349 [debug] Foo needs Elixir.BaseFoo
=INFO REPORT==== 16-Sep-2015::14:59:51 ===
application: logger
exited: stopped
type: temporary
** (Mix) Could not start application foo_controller: FooTest.start(:normal, []) returned an error: shutdown: failed to start child: SampleFoo
** (EXIT) exited in: GenServer.call(FooRegistry, {:needs, BaseFoo}, 500)
** (EXIT) time out
The timeout occurs on the Supervisor.start_child line and I cannot figure why...
Would you be so kind to help me with this please ?
Many thanks,
Josef