Skip to content

Commit fdca8b2

Browse files
José Valimfishcakez
authored andcommitted
Add docs for simple one for one
Signed-off-by: James Fish <[email protected]>
1 parent dec06d8 commit fdca8b2

File tree

1 file changed

+51
-7
lines changed

1 file changed

+51
-7
lines changed

lib/elixir/lib/supervisor.ex

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ defmodule Supervisor do
2020
defmodule Stack do
2121
use GenServer
2222
23-
def start_link(state) do
24-
GenServer.start_link(__MODULE__, state, [name: :sup_stack])
23+
def start_link(state, opts) do
24+
GenServer.start_link(__MODULE__, state, opts)
2525
end
2626
2727
def handle_call(:pop, _from, [h|t]) do
@@ -38,16 +38,17 @@ defmodule Supervisor do
3838
# Import helpers for defining supervisors
3939
import Supervisor.Spec
4040
41-
# We are going to supervise the Stack server which will
42-
# be started with a single argument [:hello]
41+
# We are going to supervise the Stack server which
42+
# will be started with a single argument [:hello]
43+
# and the default name of :sup_stack.
4344
children = [
44-
worker(Stack, [[:hello]])
45+
worker(Stack, [[:hello], [name: :sup_stack]])
4546
]
4647
4748
# Start the supervisor with our one child
4849
{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)
4950
50-
Notice that when starting the GenServer, we have registered it
51+
Notice that when starting the GenServer, we are registering it
5152
with name `:sup_stack`, which allows us to call it directly and
5253
get what is on the stack:
5354
@@ -65,7 +66,7 @@ defmodule Supervisor do
6566
Let's try it:
6667
6768
GenServer.call(:sup_stack, :pop)
68-
=ERROR REPORT====
69+
** (exit) exited in: GenServer.call(:sup_stack, :pop, 5000)
6970
7071
Luckily, since the server is being supervised by a supervisor, the
7172
supervisor will automatically start a new one, with the default stack
@@ -136,6 +137,49 @@ defmodule Supervisor do
136137
in this module behave slightly differently when this strategy is
137138
used.
138139
140+
## Simple one for one
141+
142+
The simple one for one supervisor is useful when you want to dynamically
143+
start and stop supervisor children. For example, imagine you want to
144+
dynamically create multiple stacks. We can do so by defining a simple one
145+
for one supervisor:
146+
147+
# Import helpers for defining supervisors
148+
import Supervisor.Spec
149+
150+
# This time, we don't pass any argument because
151+
# the argument will be given when we start the child
152+
children = [
153+
worker(Stack, [], restart: :transient)
154+
]
155+
156+
# Start the supervisor with our one child
157+
{:ok, sup_pid} = Supervisor.start_link(children, strategy: :simple_one_for_one)
158+
159+
There are a couple differences here:
160+
161+
* The simple one for one specification can define only one child which
162+
works as a template for when we call `start_child/2`
163+
164+
* We have define the child to have restart strategy of transient. This
165+
means that, if the child process exits due to a `:normal`, `:shutdown`
166+
or `{:shutdown, term}` reason, it won't be restarted. This is useful
167+
as it allows our workers to politely shutdown and be removed from the
168+
simple one for one supervisor, without being restarted
169+
170+
With the supervisor defined, let's dynamically start stacks:
171+
172+
{:ok, pid} = Supervisor.start_child(sup_pid, [[:hello, :world], []])
173+
GenServer.call(pid, :pop) #=> :hello
174+
GenServer.call(pid, :pop) #=> :world
175+
176+
{:ok, pid} = Supervisor.start_child(sup_pid, [[:something, :else], []])
177+
GenServer.call(pid, :pop) #=> :something
178+
GenServer.call(pid, :pop) #=> :else
179+
180+
Supervisor.count_children(sup_pid)
181+
#=> %{active: 2, specs: 1, supervisors: 0, workers: 2}
182+
139183
## Name Registration
140184
141185
A supervisor is bound to the same name registration rules as a `GenServer`.

0 commit comments

Comments
 (0)