Proposal: making differences between DynamicSupervisor and Supervisor more explicit

21 views
Skip to first unread message

Lukasz Guminski

unread,
Apr 22, 2019, 3:34:32 PM4/22/19
to elixir-lang-core
At first glance DynamicSupervisor appears to be be fully compatible with Supervisor, as it uses exactly the same method for specifying children

h DynamicSupervisor.start_child

child_spec should be a valid child specification as detailed in the
"child_spec/1" section of the documentation for Supervisor. The child process
will be started as defined in the child specification.

However, during tests (elixir 1.8.1), I noticed that DynamicSupervisor allows registering multiple children with the same id

{:ok, ds} = DynamicSupervisor.start_link(strategy: :one_for_one) 
child_spec = Supervisor.child_spec({Agent, fn -> :ok end}, id: :child, type: :worker)
Enum.each(0..5, fn _ -> {:ok, _pid} = DynamicSupervisor.start_child(ds, child_spec) end)

:ok                                          

the code above succeeds, but the same wouldn't be possible with Supervisor

{:ok, s} = Supervisor.start_link([], strategy: :one_for_one)
child_spec = Supervisor.child_spec({Agent, fn -> :ok end}, id: :child, type: :worker)
Enum.each(0..5, fn _ -> {:ok, _pid} = Supervisor.start_child(s, child_spec) end)

** (MatchError) no match of right hand side value: {:error, {:already_started, #PID<0.2977.0>}}
    (stdlib) erl_eval.erl:453: :erl_eval.expr/5
    (elixir) lib/enum.ex:775: anonymous fn/3 in Enum.each/2
    (elixir) lib/enum.ex:3003: Enum.reduce_range_inc/4
    (elixir) lib/enum.ex:1945: Enum.each/2

Moreover if you run DynamicSupervisor.which_children/1, you can see that ids are not only unchecked, but are not even preserved:

DynamicSupervisor.which_children(ds)

[
  {:undefined, #PID<0.2948.0>, :worker, [Agent]},
  {:undefined, #PID<0.2949.0>, :worker, [Agent]},
  {:undefined, #PID<0.2950.0>, :worker, [Agent]},
  {:undefined, #PID<0.2951.0>, :worker, [Agent]},
  {:undefined, #PID<0.2952.0>, :worker, [Agent]},
  {:undefined, #PID<0.2953.0>, :worker, [Agent]}
]

I think it would be beneficial if the documentation of DynamicSupervisor would be explicit about this incompatibility. Currently the documentation gives impression that behaviorally they are almost the same (except for the ability to easily impose a limit on the number of children).

José Valim

unread,
Apr 22, 2019, 4:05:26 PM4/22/19
to elixir-l...@googlegroups.com
Yup, we should definitely document that the ID is ignored. Maybe on the start_child function. A PR is welcome.
--


José Valim
Skype: jv.ptec
Founder and Director of R&D

johanna.a...@gmail.com

unread,
Apr 23, 2019, 5:06:32 AM4/23/19
to elixir-lang-core
There is a reference to it in the documentation of `which_children` in DynamicSupervisor, but that wasn't super easy to find! https://hexdocs.pm/elixir/DynamicSupervisor.html#which_children/1

I've also missed clearer documentation on this.

Reply all
Reply to author
Forward
0 new messages