Well, I am suprised. Why for a technology so cool, elegant and pleasant… the community is so … strange I did read the docs, just overlooked the “name registration” piece. No one wrote code for me to paste. It was not my intent either. I was looking for a way to call not having a pid. As simple as that. I did explain what I meant with Phoenix “use case”, got a hint from others, solved my problem, thanked, but you keep telling some stories (the entire quote about phoenix genearting code is MADE UP) and lecturing me I will think twice before I post a question next time. You guys just relax.
So then we seem to have also got your question wrong. May I apologize? It would be a pity if you left just because we talked past each other.
No need C’mon! Thank you guys for you help and I am not going to leave for sure. BTW, as an ex-Java, Scala and Clojure dev (started Java in 2002)…I must say Elixir/Phoenix rock! Hats off to all contributors.
Welcome here and I’m glad that you received the answer you was looking for.
Enjoy Elixir with us
FYI: Supervisor.Spec has been deprecated:
So in v1.5, assuming that Foo.Worker
specifies use GenServer
while FooWeb.EndPoint
and Foo.Repo
specify use Supervisor
the following should work:
def start(_type, _args) do
children = [
Foo.Repo,
FooWeb.Endpoint,
Foo.Stats
]
opts = [strategy: :one_for_one, name: Foo.Supervisor]
Supervisor.start_link(children, opts)
end
In a module-based supervisor the following approach would be typically used
defmodule Foo.Supervisor do
use Supervisor
def start_link(args),
do: Supervisor.start_link(__MODULE__, args)
def init(stash_pid) do
children = [
Foo.Repo,
FooWeb.Endpoint,
Foo.Stats
]
opts = [strategy: :one_for_one, name: __MODULE__]
Supervisor.init(children, opts)
end
end
When you specify use GenServer
in a module a child_spec/1
function is automatically added to your module which is roughly equivalent to (in truth there is more going on):
def child_spec(firstArg) do
%{
id: __MODULE__,
start: {__MODULE__, :start_link, [firstArg]},
restart: :permanent,
shutdown: 5000,
type: :worker
}
end
The child_spec/1
function is called when just the plain module name is used in the child list. You can specify the argument
children = [
Foo.Repo,
FooWeb.Endpoint,
{Foo.Stats,"My First Argument"}
]
otherwise []
is assumed. The specs can also be overridden on the module level:
use GenServer, start: {__MODULE__, :start_link, ["fixed first argument","fixed second argument"]}
use Supervisor
essentially works the same way - the only difference is that :type
is set to :supervisor
.
Alternately the supervisor can use Supervisor.child_spec/2
foo_spec = (Supervisor.child_spec Foo.Stats, start: {__MODULE__, :start_link, ["1st arg","2nd arg"]})
children = [
Foo.Repo,
FooWeb.Endpoint,
foo_spec
]
or the supervisor can just specify everything:
foo_spec = %{
id: Foo.Stats,
start: {Foo.Stats, :start_link, ["1st arg","2nd arg"]},
restart: :permanent,
shutdown: 5000,
type: :worker
}
children = [
Foo.Repo,
FooWeb.Endpoint,
foo_spec
]
One could actually nitpick as :name
isn’t an argument but simply an option - and options always occur as the last parameter and are specified as part of a keyword (list).
So
def start_link() do
GenServer.start_link(__MODULE__, [], name: Foo)
end
is in fact
def start_link() do
GenServer.start_link(__MODULE__, [], [{:name, Foo}])
end