Skip to content

Commit 8d26993

Browse files
author
José Valim
committed
Streamline supervisor docs
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
1 parent c1c4b1a commit 8d26993

File tree

1 file changed

+89
-111
lines changed

1 file changed

+89
-111
lines changed

lib/elixir/lib/supervisor.ex

Lines changed: 89 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -99,48 +99,9 @@ defmodule Supervisor do
9999
workers and/or supervisors as children, with each one having its own
100100
configuration (as outlined in the "Child specification" section).
101101
102-
The rest of this document will cover how child processes are started,
103-
how they can be specified, different supervision strategies and more.
104-
105-
## Start and shutdown
106-
107-
When the supervisor starts, it traverses all child specifications and
108-
then starts each child in the order they are defined. This is done by
109-
calling the function defined under the `:start` key in the child
110-
specification and typically defaults to `start_link/1`.
111-
112-
The `start_link/1` (or a custom) is then called for each child process.
113-
The `start_link/1` function must return `{:ok, pid}` where `pid` is the
114-
process identifier of a new process that is linked to the supervisor.
115-
The child process usually starts its work by executing the `init/1`
116-
callback. Generally speaking, the `init` callback is where we initialize
117-
and configure the child process.
118-
119-
The shutdown process happens in reverse order.
120-
121-
When a supervisor shuts down, it terminates all children in the opposite
122-
order they are listed. The termination happens by sending a shutdown exit
123-
signal, via `Process.exit(child_pid, :shutdown)`, to the child process and
124-
then awaiting for a time interval for the child process to terminate. This
125-
interval defaults to 5000 milliseconds. If the child process does not
126-
terminate in this interval, the supervisor abruptly terminates the child
127-
with reason `:kill`. The shutdown time can be configured in the child
128-
specification which is fully detailed in the next section.
129-
130-
If the child process is not trapping exits, it will shutdown immediately
131-
when it receives the first exit signal. If the child process is trapping
132-
exits, then the `terminate` callback is invoked, and the child process
133-
must terminate in a reasonable time interval before being abruptly
134-
terminated by the supervisor.
135-
136-
In other words, if it is important that a process cleans after itself
137-
when your application or the supervision tree is shutting down, then
138-
this process must trap exits and its child specification should specify
139-
the proper `:shutdown` value, ensuring it terminates within a reasonable
140-
interval.
141-
142-
Now that we understand the start and shutdown process, let's take a
143-
complete look at all of the options provided in the child specification.
102+
The rest of this document will cover how child processes are specified,
103+
how they can be started and stopped, different supervision strategies
104+
and more.
144105
145106
## Child specification
146107
@@ -247,30 +208,31 @@ defmodule Supervisor do
247208
248209
The supervisor will then invoke `Stack.child_spec([:hello])` to retrieve a
249210
child specification. Now the `Stack` module is responsible for building its
250-
own specification. By default, `use GenServer` defines a `Stack.child_spec/1`
251-
function which returns the same child specification we had before:
211+
own specification, for example, we could write:
252212
253-
%{
254-
id: Stack,
255-
start: {Stack, :start_link, [[:hello]]}
256-
}
213+
def child_spec(arg) do
214+
%{
215+
id: Stack,
216+
start: {Stack, :start_link, [arg]}
217+
}
218+
end
219+
220+
Luckily for us, `use GenServer` already defines a `Stack.child_spec/1`
221+
exactly like above. If you need to customize the `GenServer`, you can
222+
pass the options directly to `use GenServer`:
223+
224+
use GenServer, restart: :transient
257225
258-
It is also possible to simply pass the `Stack` module as a child:
226+
Finally, note it is also possible to simply pass the `Stack` module as
227+
a child:
259228
260229
children = [
261230
Stack
262231
]
263232
264-
When only the module name is given, it is equivalent to `{Stack, []}`. In this
265-
case, we will end-up with a child specification that looks like this:
266-
267-
%{
268-
id: Stack,
269-
start: {Stack, :start_link, [[]]}
270-
}
271-
233+
When only the module name is given, it is equivalent to `{Stack, []}`.
272234
By replacing the map specification by `{Stack, [:hello]}` or `Stack`, we keep
273-
the child specification encapsulated in the Stack module, using the default
235+
the child specification encapsulated in the `Stack` module, using the default
274236
implementation defined by `use GenServer`. We can now share our `Stack` worker
275237
with other developers and they can add it directly to their supervision tree
276238
without worrying about the low-level details of the worker.
@@ -294,55 +256,6 @@ defmodule Supervisor do
294256
Supervisor.child_spec({Stack, [:hello]}, id: MyStack, shutdown: 10_000)
295257
]
296258
297-
The call to `Supervisor.child_spec/2` above will return the following specification:
298-
299-
%{
300-
id: MyStack,
301-
start: {Stack, :start_link, [[:hello]]},
302-
shutdown: 10_000
303-
}
304-
305-
You may also configure the child specification in the Stack module itself to
306-
use a different `:id` or `:shutdown` value by passing options to `use GenServer`:
307-
308-
defmodule Stack do
309-
use GenServer, id: MyStack, shutdown: 10_000
310-
311-
The options above will customize the `Stack.child_spec/1` function defined
312-
by `use GenServer`. It accepts the same options as the `Supervisor.child_spec/2`
313-
function.
314-
315-
You may also completely override the `child_spec/1` function in the Stack module
316-
and return your own child specification. Note there is no guarantee the `child_spec/1`
317-
function will be called by the Supervisor process, as other processes may invoke
318-
it to retrieve the child specification before reaching the supervisor.
319-
320-
## Exit reasons and restarts
321-
322-
A supervisor restarts a child process depending on its `:restart`
323-
configuration. For example, when `:restart` is set to `:transient`, the
324-
supervisor does not restart the child in case it exits with reason `:normal`,
325-
`:shutdown` or `{:shutdown, term}`.
326-
327-
So one may ask: which exit reason should I choose when exiting? There are
328-
three options:
329-
330-
* `:normal` - in such cases, the exit won't be logged, there is no restart
331-
in transient mode, and linked processes do not exit
332-
333-
* `:shutdown` or `{:shutdown, term}` - in such cases, the exit won't be
334-
logged, there is no restart in transient mode, and linked processes exit
335-
with the same reason unless they're trapping exits
336-
337-
* any other term - in such cases, the exit will be logged, there are
338-
restarts in transient mode, and linked processes exit with the same
339-
reason unless they're trapping exits
340-
341-
Notice that the supervisor that reaches maximum restart intensity will exit with
342-
`:shutdown` reason. In this case the supervisor will only be restarted if its
343-
child specification was defined with the `:restart` option set to `:permanent`
344-
(the default).
345-
346259
## Module-based supervisors
347260
348261
In the example above, a supervisor was started by passing the supervision
@@ -375,7 +288,8 @@ defmodule Supervisor do
375288
`c:init/1` callback.
376289
377290
`use Supervisor` also defines a `child_spec/1` function which allows
378-
us to run `MyApp.Supervisor` as a child of another supervisor:
291+
us to run `MyApp.Supervisor` as a child of another supervisor or
292+
at the top of your supervision tree as:
379293
380294
children = [
381295
MyApp.Supervisor
@@ -387,8 +301,9 @@ defmodule Supervisor do
387301
module only at the top of your supervision tree, generally in the
388302
`c:Application.start/2` callback. We recommend using module-based
389303
supervisors for any other supervisor in your application, so they
390-
can run as a child of another supervision in the tree. The generated
391-
`child_spec/1` can be customized with the following options:
304+
can run as a child of another supervisor in the tree. The `child_spec/1`
305+
generated automatically by `Supervisor` can be customized with the
306+
following options:
392307
393308
* `:id` - the child specification identifier, defaults to the current module
394309
* `:start` - how to start the child process (defaults to calling `__MODULE__.start_link/1`)
@@ -461,10 +376,73 @@ defmodule Supervisor do
461376
differently when this strategy was used. See the `DynamicSupervisor` module
462377
for more information and migration strategies.
463378
464-
## Name registration
379+
### Name registration
465380
466381
A supervisor is bound to the same name registration rules as a `GenServer`.
467382
Read more about these rules in the documentation for `GenServer`.
383+
384+
## Start and shutdown
385+
386+
When the supervisor starts, it traverses all child specifications and
387+
then starts each child in the order they are defined. This is done by
388+
calling the function defined under the `:start` key in the child
389+
specification and typically defaults to `start_link/1`.
390+
391+
The `start_link/1` (or a custom) is then called for each child process.
392+
The `start_link/1` function must return `{:ok, pid}` where `pid` is the
393+
process identifier of a new process that is linked to the supervisor.
394+
The child process usually starts its work by executing the `init/1`
395+
callback. Generally speaking, the `init` callback is where we initialize
396+
and configure the child process.
397+
398+
The shutdown process happens in reverse order.
399+
400+
When a supervisor shuts down, it terminates all children in the opposite
401+
order they are listed. The termination happens by sending a shutdown exit
402+
signal, via `Process.exit(child_pid, :shutdown)`, to the child process and
403+
then awaiting for a time interval for the child process to terminate. This
404+
interval defaults to 5000 milliseconds. If the child process does not
405+
terminate in this interval, the supervisor abruptly terminates the child
406+
with reason `:kill`. The shutdown time can be configured in the child
407+
specification which is fully detailed in the next section.
408+
409+
If the child process is not trapping exits, it will shutdown immediately
410+
when it receives the first exit signal. If the child process is trapping
411+
exits, then the `terminate` callback is invoked, and the child process
412+
must terminate in a reasonable time interval before being abruptly
413+
terminated by the supervisor.
414+
415+
In other words, if it is important that a process cleans after itself
416+
when your application or the supervision tree is shutting down, then
417+
this process must trap exits and its child specification should specify
418+
the proper `:shutdown` value, ensuring it terminates within a reasonable
419+
interval.
420+
421+
## Exit reasons and restarts
422+
423+
A supervisor restarts a child process depending on its `:restart` configuration.
424+
For example, when `:restart` is set to `:transient`, the supervisor does not
425+
restart the child in case it exits with reason `:normal`, `:shutdown` or
426+
`{:shutdown, term}`.
427+
428+
So one may ask: which exit reason should I choose when exiting? There are
429+
three options:
430+
431+
* `:normal` - in such cases, the exit won't be logged, there is no restart
432+
in transient mode, and linked processes do not exit
433+
434+
* `:shutdown` or `{:shutdown, term}` - in such cases, the exit won't be
435+
logged, there is no restart in transient mode, and linked processes exit
436+
with the same reason unless they're trapping exits
437+
438+
* any other term - in such cases, the exit will be logged, there are
439+
restarts in transient mode, and linked processes exit with the same
440+
reason unless they're trapping exits
441+
442+
Notice that the supervisor that reaches maximum restart intensity will exit with
443+
`:shutdown` reason. In this case the supervisor will only be restarted if its
444+
child specification was defined with the `:restart` option set to `:permanent`
445+
(the default).
468446
"""
469447

470448
@doc false

0 commit comments

Comments
 (0)