@@ -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