3 ms·
They are probably talking about the child spec needing a unique ID if it's the same module being started. The docs problem is more of a Google problem. For som
by dqv 2y ago
They are probably talking about the child spec needing a unique ID if it's the same module being started.
The docs problem is more of a Google problem. For some reason Google still only shows the 1.12 docs for a lot of searches. The sidebar issue was fixed more recently, I think in the last year. But basically the sidebar wouldn't get loaded until Mermaid finished loading, so it was updated to defer loading of Mermaid. The latest version of ExDoc shouldn't have this problem.
- simoncion 2y ago> They are probably talking about the child spec needing a unique ID if it's the same module being started. No, my experience says that's not true. I have this code in one of my projects and it works just fine: -behavior(gen_server). start(Mod, Args) -> supervisor:start_child(secret_project_worker_sup:getName(), [{Mod, Args}]). I can spawn as many of those guys as I like and they all become children of the named supervisor. The named supervisor is a 'simple_one_for_one' supervisor with a 'temporary' restart policy. I guess the thing that might trip folks up with how the docs are worded is not noticing this further up in the document A supervisor can have one of the following restart strategies specified with the strategy key in the above map: ... * simple_one_for_one - A simplified one_for_one supervisor, where all child processes are dynamically added instances of the same process type, that is, running the same code. and that 'start_child/2' accepts EITHER a 'child_spec()' OR a list of terms -spec start_child(SupRef, ChildSpec) -> startchild_ret() when SupRef :: sup_ref(), ChildSpec :: child_spec(); (SupRef, ExtraArgs) -> startchild_ret() when SupRef :: sup_ref(), ExtraArgs :: [term()]. and that only the 'child_spec()' type can have an identifier, so the first bullet point in the list of three in the function documentation does not apply. Also, I find the way the docs USED to print out function types a bit easier to understand than the new style: <https://web.archive.org/web/20170509120825/http://erlang.org/doc/man/supervisor.html#start_child-2 https://web.archive.org/web/20170509120825/http://erlang.org...>. (You will need to either close the Archive.org nav banner or scroll up a line to see the first line of the function type information, which is pretty informative.)
- dqv 2y agoI'm talking about the behavior of the one_for_one supervisor: defmodule Testing.Application do use Application @impl Application def start(_type, _args) do children = [] opts = [strategy: :one_for_one, name: Testing.Supervisor] Supervisor.start_link(children, opts) end end defmodule Testing.Server do use GenServer def start_link(_), do: GenServer.start_link(__MODULE__, []) @impl GenServer def init(_), do: {:ok, nil} end When you try to start more than one child, it fails: Erlang/OTP 25 [erts-13.2.2.11] [source] [64-bit] [smp:14:14] [ds:14:14:10] [async-threads:1] [jit:ns] Interactive Elixir (1.17.3) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> Supervisor.start_child(Testing.Supervisor, {Testing.Server, []}) {:ok, #PID<0.135.0>} iex(2)> Supervisor.start_child(Testing.Supervisor, {Testing.Server, [:x]}) {:error, {:already_started, #PID<0.135.0>}} But defining a child spec that sets the id: defmodule Testing.Server do use GenServer def start_link(_), do: GenServer.start_link(__MODULE__, []) def child_spec(arg) do id = Keyword.get(arg, :id) %{id: id, start: {__MODULE__, :start_link, [[]]}} end @impl GenServer def init(_), do: {:ok, nil} end solves the problem: Erlang/OTP 25 [erts-13.2.2.11] [source] [64-bit] [smp:14:14] [ds:14:14:10] [async-threads:1] [jit:ns] Interactive Elixir (1.17.3) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> Supervisor.start_child(Testing.Supervisor, {Testing.Server, id: 1}) {:ok, #PID<0.135.0>} iex(2)> Supervisor.start_child(Testing.Supervisor, {Testing.Server, id: 1}) {:error, {:already_started, #PID<0.135.0>}} iex(3)> Supervisor.start_child(Testing.Supervisor, {Testing.Server, id: 2}) {:ok, #PID<0.136.0>}
- simoncion 2y ago> I'm talking about the behavior of the one_for_one supervisor: Oh, sure, you can vary the ID in non-'simple_one_for_one' supervisors there to make that work. Apologies for inducing you to write out all that transcript and code. But, OP's claim was: > - a lot of knowledge is implicit (try checking if you can dynamically add children to a Supervisor) which is just not fucking true no matter how you slice it. It's true that the relevant documentation doesn't literally say "Calling 'start_child/2' is valid for any kind of 'supervisor'. That's why it's here... to dynamically add children to a 'supervisor'.", but if one bothers to read the docs on supervisors and the function in question it's clear that that's the entire point of 'start_child/2'.