In the Task.Supervisor docs, it states
You can also start it by calling start_link/1 directly … But this is recommended only for scripting and should be avoided in production code. Generally speaking, processes should always be started inside supervision trees.
However, this is not elaborated on.
In an application I’m writing, my supervision tree contains some number of instances of a single GenServer. This GenServer will spawn several tasks during its lifetime whose return value I care about; they are not fire and forget. As part of the GenServer’s state, I store the pid of a Task.Supervisor that I start in GenServer.init/1. In my mind, this makes sense, because if theTask.Supervisor crashes (due to too many task failures or what have you), my GenServer crashes and its supervisor restarts it.
If, however, I were to run the Task.Supervisor and the GenServer under the same supervision tree, I foresee race conditions where the GenServer is trying to spawn a task on a currently restarting Task.Supervisor (e.g. imagine that the Task.Supervisor has crashed, and before its supervisor restarts it, the GenServer attempts to spawn a task… this will surely fail). I can imagine this becoming exacerbated as more of the GenServers send tasks to this supervisor, as it will be even easier to trip the max_restarts of the Task.Supervisor,
Why do the docs say to prefer this approach?






















