Why start_link/1 by default on child_spec


I am confused by the various start_link/X signatures and the number of arguments they accept depending on the context (and especially the fact that default child_specs use start_link/1, preventing from sending options in addition to args).

What I want to do is to start several instances of a given GenServer by specifying a :name, something that would look like (without a Supervisor):

GenServer.start_link(Stack, args1, name: :stack1)
GenServer.start_link(Stack, args2, name: :stack2)

In this case it’s possible to spawn GenServers with specific args and names.

Now with a Supervisor, the steps are (see doc):

1 - create a spec with an empty args list so that it can be overriden by each child (I don’t understand why it is necessary since we are going to specify a :simple_one_for_one strategy right after). The doc gives this example:

spec = Supervisor.child_spec(Agent, start: {Agent, :start_link, []})

But in a module we can also override the spec:

defmodule Stack do
  use Agent, start: {Stack, :start_link, []}
spec = Stack.child_spec(:useless_ugly_parameter)

Or even define a child_spec/0 without this :useless_ugly_parameter.

2 - Start the supervisor with the spec:

{:ok, sup_pid} = Supervisor.start_link([spec], strategy: :simple_one_for_one)

3 - Start children:

{:ok, child1} = Supervisor.start_child(sup_pid, [args1])
{:ok, child2} = Supervisor.start_child(sup_pid, [args2])

Now it seems it’s not possible to send options (like :name) to child with start_child.

Possible solutions:

  • put the options in the args, something like:
{:ok, child} = Supervisor.start_child(sup_pid, [{args, options}])

And within Stack.start_link/1 destructure it so that we only send args to init/1. Something like:

def start_link({args, options}) do
    GenServer.start_link(__MODULE, args, options)
  • or define a child spec that would use start_link/2 (rather than start_link/1), but I don’t know how to do it.

Even if both may be possible, I think this adds complexity to a typical scenario.

1 Like