Task.Supervisor
A task supervisor.
This module defines a supervisor which can be used to dynamically supervise tasks. Behind the scenes, this module is implemented as a :simple_one_for_one
supervisor where the workers are temporary by default (that is, they are not restarted after they die; read the docs for start_link/1
for more information on choosing the restart strategy).
See the Task
module for more information.
Name registration
A Task.Supervisor
is bound to the same name registration rules as a GenServer
. Read more about them in the GenServer
docs.
Summary
Functions
- async(supervisor, fun)
-
Starts a task that can be awaited on
- async(supervisor, module, fun, args)
-
Starts a task that can be awaited on
- async_nolink(supervisor, fun)
-
Starts a task that can be awaited on
- async_nolink(supervisor, module, fun, args)
-
Starts a task that can be awaited on
- async_stream(supervisor, enumerable, fun, options \\ [])
-
Returns a stream that runs the given
function
concurrently on each item inenumerable
- async_stream(supervisor, enumerable, module, function, args, options \\ [])
-
Returns a stream that runs the given
module
,function
andargs
concurrently on each item inenumerable
- async_stream_nolink(supervisor, enumerable, fun, options \\ [])
-
Returns a stream that runs the given
function
concurrently on each item inenumerable
- async_stream_nolink(supervisor, enumerable, module, function, args, options \\ [])
-
Returns a stream that runs the given
module
,function
andargs
concurrently on each item inenumerable
- children(supervisor)
-
Returns all children PIDs
- start_child(supervisor, fun)
-
Starts a task as a child of the given
supervisor
- start_child(supervisor, module, fun, args)
-
Starts a task as a child of the given
supervisor
- start_link(opts \\ [])
-
Starts a new supervisor
- terminate_child(supervisor, pid)
-
Terminates the child with the given
pid
Functions
async(supervisor, fun)
async(Supervisor.supervisor(), (... -> any())) :: Task.t()
Starts a task that can be awaited on.
The supervisor
must be a reference as defined in Task.Supervisor
. The task will still be linked to the caller, see Task.async/3
for more information and async_nolink/2
for a non-linked variant.
async(supervisor, module, fun, args)
async(Supervisor.supervisor(), module(), atom(), [term()]) :: Task.t()
Starts a task that can be awaited on.
The supervisor
must be a reference as defined in Task.Supervisor
. The task will still be linked to the caller, see Task.async/3
for more information and async_nolink/2
for a non-linked variant.
async_nolink(supervisor, fun)
async_nolink(Supervisor.supervisor(), (... -> any())) :: Task.t()
Starts a task that can be awaited on.
The supervisor
must be a reference as defined in Task.Supervisor
. The task won’t be linked to the caller, see Task.async/3
for more information.
Compatibility with OTP behaviours
If you create a task using async_nolink
inside an OTP behaviour like GenServer
, you should match on the message coming from the task inside your GenServer.handle_info/2
callback.
The reply sent by the task will be in the format {ref, result}
, where ref
is the monitor reference held by the task struct and result
is the return value of the task function.
Keep in mind that, regardless of how the task created with async_nolink
terminates, the caller’s process will always receive a :DOWN
message with the same ref
value that is held by the task struct. If the task terminates normally, the reason in the :DOWN
message will be :normal
.
async_nolink(supervisor, module, fun, args)
async_nolink(Supervisor.supervisor(), module(), atom(), [term()]) :: Task.t()
Starts a task that can be awaited on.
The supervisor
must be a reference as defined in Task.Supervisor
. The task won’t be linked to the caller, see Task.async/3
for more information.
async_stream(supervisor, enumerable, fun, options \\ [])
async_stream(Supervisor.supervisor(), Enumerable.t(), (term() -> term()), Keyword.t()) :: Enumerable.t()
Returns a stream that runs the given function
concurrently on each item in enumerable
.
Each item will be appended to the given args
and processed by its own task. The tasks will be spawned under the given supervisor
and are linked to the current process, similar to async/2
.
See async_stream/6
for discussion and examples.
async_stream(supervisor, enumerable, module, function, args, options \\ [])
async_stream(Supervisor.supervisor(), Enumerable.t(), module(), atom(), [term()], Keyword.t()) :: Enumerable.t()
Returns a stream that runs the given module
, function
and args
concurrently on each item in enumerable
.
Each item will be appended to the given args
and processed by its own task. The tasks will be spawned under the given supervisor
and linked to the current process, similar to async/4
.
When streamed, each task will emit {:ok, val}
upon successful completion or {:exit, val}
if the caller is trapping exits. Results are emitted in the same order as the original enumerable
.
The level of concurrency can be controlled via the :max_concurrency
option and defaults to System.schedulers_online/0
. The timeout can also be given as option and defaults to 5000 and it defaults to the maximum amount of time to wait without a task reply.
Finally, if you find yourself trapping exits to handle exits inside the async stream, consider using async_stream_nolink/6
to start tasks that are not linked to the current process.
Options
-
:max_concurrency
- sets the maximum number of tasks to run at the same time. Defaults toSystem.schedulers_online/0
. -
:timeout
- the maximum amount of time to wait without receiving a task reply (across all running tasks). Defaults to5000
.
Examples
Let’s build a stream and then enumerate it:
stream = Task.Supervisor.async_stream(MySupervisor, collection, Mod, :expensive_fun, []) Enum.to_list(stream)
async_stream_nolink(supervisor, enumerable, fun, options \\ [])
async_stream_nolink(Supervisor.supervisor(), Enumerable.t(), (term() -> term()), Keyword.t()) :: Enumerable.t()
Returns a stream that runs the given function
concurrently on each item in enumerable
.
Each item will be appended to the given args
and processed by its own task. The tasks will be spawned under the given supervisor
and are not linked to the current process, similar to async_nolink/2
.
See async_stream/6
for discussion and examples.
async_stream_nolink(supervisor, enumerable, module, function, args, options \\ [])
async_stream_nolink(Supervisor.supervisor(), Enumerable.t(), module(), atom(), [term()], Keyword.t()) :: Enumerable.t()
Returns a stream that runs the given module
, function
and args
concurrently on each item in enumerable
.
Each item will be appended to the given args
and processed by its own task. The tasks will be spawned under the given supervisor
and are not linked to the current process, similar to async_nolink/4
.
See async_stream/6
for discussion and examples.
children(supervisor)
children(Supervisor.supervisor()) :: [pid()]
Returns all children PIDs.
start_child(supervisor, fun)
start_child(Supervisor.supervisor(), (... -> any())) :: {:ok, pid()}
Starts a task as a child of the given supervisor
.
Note that the spawned process is not linked to the caller, but only to the supervisor. This command is useful in case the task needs to perform side-effects (like I/O) and does not need to report back to the caller.
start_child(supervisor, module, fun, args)
start_child(Supervisor.supervisor(), module(), atom(), [term()]) :: {:ok, pid()}
Starts a task as a child of the given supervisor
.
Similar to start_child/2
except the task is specified by the given module
, fun
and args
.
start_link(opts \\ [])
start_link(Supervisor.options()) :: Supervisor.on_start()
Starts a new supervisor.
The supported options are:
-
:name
- used to register a supervisor name, the supported values are described under theName Registration
section in theGenServer
module docs; -
:restart
- the restart strategy, may be:temporary
(the default),:transient
or:permanent
. CheckSupervisor.Spec
for more info. Defaults to:temporary
so tasks aren’t automatically restarted when they complete nor in case of crashes; -
:shutdown
-:brutal_kill
if the tasks must be killed directly on shutdown or an integer indicating the timeout value, defaults to 5000 milliseconds; -
:max_restarts
and:max_seconds
- as specified inSupervisor.Spec.supervise/2
;
terminate_child(supervisor, pid)
terminate_child(Supervisor.supervisor(), pid()) :: :ok
Terminates the child with the given pid
.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.4.5/Task.Supervisor.html