1defmodule Supervisor.Spec do 2 @moduledoc """ 3 Outdated functions for building child specifications. 4 5 The functions in this module are deprecated and they do not work 6 with the module-based child specs introduced in Elixir v1.5. 7 Please see the `Supervisor` documentation instead. 8 9 Convenience functions for defining supervisor specifications. 10 11 ## Example 12 13 By using the functions in this module one can specify the children 14 to be used under a supervisor, started with `Supervisor.start_link/2`: 15 16 import Supervisor.Spec 17 18 children = [ 19 worker(MyWorker, [arg1, arg2, arg3]), 20 supervisor(MySupervisor, [arg1]) 21 ] 22 23 Supervisor.start_link(children, strategy: :one_for_one) 24 25 Sometimes, it may be handy to define supervisors backed 26 by a module: 27 28 defmodule MySupervisor do 29 use Supervisor 30 31 def start_link(arg) do 32 Supervisor.start_link(__MODULE__, arg) 33 end 34 35 def init(arg) do 36 children = [ 37 worker(MyWorker, [arg], restart: :temporary) 38 ] 39 40 supervise(children, strategy: :simple_one_for_one) 41 end 42 end 43 44 Note that in this case we don't have to explicitly import 45 `Supervisor.Spec` since `use Supervisor` automatically does so. 46 Defining a module-based supervisor can be useful, for example, 47 to perform initialization tasks in the `c:Supervisor.init/1` callback. 48 49 ## Supervisor and worker options 50 51 In the example above, we defined specs for workers and supervisors. 52 These specs (both for workers as well as supervisors) accept the 53 following options: 54 55 * `:id` - a name used to identify the child specification 56 internally by the supervisor; defaults to the given module 57 name for the child worker/supervisor 58 59 * `:function` - the function to invoke on the child to start it 60 61 * `:restart` - an atom that defines when a terminated child process should 62 be restarted (see the "Restart values" section below) 63 64 * `:shutdown` - an atom that defines how a child process should be 65 terminated (see the "Shutdown values" section below) 66 67 * `:modules` - it should be a list with one element `[module]`, 68 where module is the name of the callback module only if the 69 child process is a `Supervisor` or `GenServer`; if the child 70 process is a `GenEvent`, `:modules` should be `:dynamic` 71 72 ### Restart values (:restart) 73 74 The following restart values are supported in the `:restart` option: 75 76 * `:permanent` - the child process is always restarted 77 78 * `:temporary` - the child process is never restarted (not even 79 when the supervisor's strategy is `:rest_for_one` or `:one_for_all`) 80 81 * `:transient` - the child process is restarted only if it 82 terminates abnormally, i.e., with an exit reason other than 83 `:normal`, `:shutdown` or `{:shutdown, term}` 84 85 Note that supervisor that reached maximum restart intensity will exit with `:shutdown` reason. 86 In this case the supervisor will only restart if its child specification was defined with 87 the `:restart` option set to `:permanent` (the default). 88 89 ### Shutdown values (`:shutdown`) 90 91 The following shutdown values are supported in the `:shutdown` option: 92 93 * `:brutal_kill` - the child process is unconditionally terminated 94 using `Process.exit(child, :kill)` 95 96 * `:infinity` - if the child process is a supervisor, this is a mechanism 97 to give the subtree enough time to shut down; it can also be used with 98 workers with care 99 100 * a non-negative integer - the amount of time in milliseconds 101 that the supervisor tells the child process to terminate by calling 102 `Process.exit(child, :shutdown)` and then waits for an exit signal back. 103 If no exit signal is received within the specified time, 104 the child process is unconditionally terminated 105 using `Process.exit(child, :kill)` 106 107 """ 108 109 @moduledoc deprecated: 110 "Use the new child specifications outlined in the Supervisor module instead" 111 112 @typedoc "Supported strategies" 113 @type strategy :: :simple_one_for_one | :one_for_one | :one_for_all | :rest_for_one 114 115 @typedoc "Supported restart values" 116 @type restart :: :permanent | :transient | :temporary 117 118 @typedoc "Supported shutdown values" 119 @type shutdown :: timeout | :brutal_kill 120 121 @typedoc "Supported worker values" 122 @type worker :: :worker | :supervisor 123 124 @typedoc "Supported module values" 125 @type modules :: :dynamic | [module] 126 127 @typedoc "Supported ID values" 128 @type child_id :: term 129 130 @typedoc "The supervisor specification" 131 @type spec :: 132 {child_id, start_fun :: {module, atom, [term]}, restart, shutdown, worker, modules} 133 134 @doc """ 135 Receives a list of `children` (workers or supervisors) to 136 supervise and a set of `options`. 137 138 Returns a tuple containing the supervisor specification. This tuple can be 139 used as the return value of the `c:Supervisor.init/1` callback when implementing a 140 module-based supervisor. 141 142 ## Examples 143 144 supervise(children, strategy: :one_for_one) 145 146 ## Options 147 148 * `:strategy` - the restart strategy option. It can be either 149 `:one_for_one`, `:rest_for_one`, `:one_for_all`, or 150 `:simple_one_for_one`. You can learn more about strategies 151 in the `Supervisor` module docs. 152 153 * `:max_restarts` - the maximum number of restarts allowed in 154 a time frame. Defaults to `3`. 155 156 * `:max_seconds` - the time frame in which `:max_restarts` applies. 157 Defaults to `5`. 158 159 The `:strategy` option is required and by default a maximum of 3 restarts is 160 allowed within 5 seconds. Check the `Supervisor` module for a detailed 161 description of the available strategies. 162 """ 163 @spec supervise( 164 [spec], 165 strategy: strategy, 166 max_restarts: non_neg_integer, 167 max_seconds: pos_integer 168 ) :: {:ok, tuple} 169 @deprecated "Use the new child specifications outlined in the Supervisor module instead" 170 def supervise(children, options) do 171 unless strategy = options[:strategy] do 172 raise ArgumentError, "expected :strategy option to be given" 173 end 174 175 maxR = Keyword.get(options, :max_restarts, 3) 176 maxS = Keyword.get(options, :max_seconds, 5) 177 178 assert_unique_ids(Enum.map(children, &get_id/1)) 179 {:ok, {{strategy, maxR, maxS}, children}} 180 end 181 182 defp get_id({id, _, _, _, _, _}) do 183 id 184 end 185 186 defp get_id(other) do 187 raise ArgumentError, 188 "invalid tuple specification given to supervise/2. If you are trying to use " <> 189 "the map child specification that is part of the Elixir v1.5, use Supervisor.init/2 " <> 190 "instead of Supervisor.Spec.supervise/2. See the Supervisor module for more information. " <> 191 "Got: #{inspect(other)}" 192 end 193 194 defp assert_unique_ids([id | rest]) do 195 if id in rest do 196 raise ArgumentError, 197 "duplicated ID #{inspect(id)} found in the supervisor specification, " <> 198 "please explicitly pass the :id option when defining this worker/supervisor" 199 else 200 assert_unique_ids(rest) 201 end 202 end 203 204 defp assert_unique_ids([]) do 205 :ok 206 end 207 208 @doc """ 209 Defines the given `module` as a worker which will be started 210 with the given arguments. 211 212 worker(ExUnit.Runner, [], restart: :permanent) 213 214 By default, the function `start_link` is invoked on the given 215 module. Overall, the default values for the options are: 216 217 [ 218 id: module, 219 function: :start_link, 220 restart: :permanent, 221 shutdown: 5000, 222 modules: [module] 223 ] 224 225 See the "Supervisor and worker options" section in the `Supervisor.Spec` module for more 226 information on the available options. 227 """ 228 @spec worker( 229 module, 230 [term], 231 restart: restart, 232 shutdown: shutdown, 233 id: term, 234 function: atom, 235 modules: modules 236 ) :: spec 237 @deprecated "Use the new child specifications outlined in the Supervisor module instead" 238 def worker(module, args, options \\ []) do 239 child(:worker, module, args, options) 240 end 241 242 @doc """ 243 Defines the given `module` as a supervisor which will be started 244 with the given arguments. 245 246 supervisor(module, [], restart: :permanent) 247 248 By default, the function `start_link` is invoked on the given 249 module. Overall, the default values for the options are: 250 251 [ 252 id: module, 253 function: :start_link, 254 restart: :permanent, 255 shutdown: :infinity, 256 modules: [module] 257 ] 258 259 See the "Supervisor and worker options" section in the `Supervisor.Spec` module for more 260 information on the available options. 261 """ 262 @spec supervisor( 263 module, 264 [term], 265 restart: restart, 266 shutdown: shutdown, 267 id: term, 268 function: atom, 269 modules: modules 270 ) :: spec 271 @deprecated "Use the new child specifications outlined in the Supervisor module instead" 272 def supervisor(module, args, options \\ []) do 273 options = Keyword.put_new(options, :shutdown, :infinity) 274 child(:supervisor, module, args, options) 275 end 276 277 defp child(type, module, args, options) do 278 id = Keyword.get(options, :id, module) 279 modules = Keyword.get(options, :modules, modules(module)) 280 function = Keyword.get(options, :function, :start_link) 281 restart = Keyword.get(options, :restart, :permanent) 282 shutdown = Keyword.get(options, :shutdown, 5000) 283 284 {id, {module, function, args}, restart, shutdown, type, modules} 285 end 286 287 defp modules(GenEvent), do: :dynamic 288 defp modules(module), do: [module] 289end 290