Elixir v1.5.0-rc.2 Task.Supervisor View Source
A task supervisor.
This module defines a supervisor which can be used to dynamically supervise tasks.
start_link/1
can be used to start the supervisor. See the Task
module for more examples.
Name registration
A Task.Supervisor
is bound to the same name registration rules as a
GenServer
. Read more about them in the GenServer
docs.
Link to this section Summary
Functions
Starts a task that can be awaited on
Starts a task that can be awaited on
Starts a task that can be awaited on
Starts a task that can be awaited on
Returns a stream that runs the given function fun
concurrently
on each item in enumerable
Returns a stream that runs the given module
, function
, and args
concurrently on each item in enumerable
Returns a stream that runs the given function
concurrently on each
item in enumerable
Returns a stream that runs the given module
, function
, and args
concurrently on each item in enumerable
Returns all children PIDs
Starts a task as a child of the given supervisor
Starts a task as a child of the given supervisor
Starts a new supervisor
Terminates the child with the given pid
Link to this section Types
option() :: Supervisor.option() | {:restart, :supervisor.restart()} | {:shutdown, :supervisor.shutdown()}
Option values used by start_link
Link to this section Functions
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.
Note this function requires the task supervisor to have :temporary
as the :restart
option (the default), as async/2
keeps a direct
reference to the task which is lost if the task is restarted.
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.
Note this function requires the task supervisor to have :temporary
as the :restart
option (the default), as async/4
keeps a direct
reference to the task which is lost if the task is restarted.
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.
Note this function requires the task supervisor to have :temporary
as the :restart
option (the default), as async_nolink/2
keeps a
direct reference to the task which is lost if the task is restarted.
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.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.
Note this function requires the task supervisor to have :temporary
as the :restart
option (the default), as async_nolink/4
keeps a
direct reference to the task which is lost if the task is restarted.
async_stream(Supervisor.supervisor(), Enumerable.t(), (term() -> term()), keyword()) :: Enumerable.t()
Returns a stream that runs the given function fun
concurrently
on each item in enumerable
.
Each item in enumerable
is passed as argument to the given function fun
and processed by its own task. The tasks will be spawned under the given
supervisor
and linked to the current process, similarly to async/2
.
See async_stream/6
for discussion, options, and examples.
async_stream(Supervisor.supervisor(), Enumerable.t(), module(), atom(), [term()], keyword()) :: Enumerable.t()
Returns a stream that runs the given module
, function
, and args
concurrently on each item in enumerable
.
Each item will be prepended 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, similarly to async/4
.
When streamed, each task will emit {:ok, value}
upon successful
completion or {:exit, reason, element}
if the caller is trapping
exits, where element
is the stream element. 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
. A timeout
can also be given as an option representing the maximum amount of
time to wait without a task reply.
Note this function requires the task supervisor to have :temporary
as the :restart
option (the default), as async_stream/6
keeps a
direct reference to the task which is lost if the task is restarted.
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
.:ordered
- whether the results should be returned in the same order as the input stream. This option is useful when you have large streams and don’t want to buffer results before they are delivered. Defaults totrue
.:timeout
- the maximum amount of time to wait (in milliseconds) without receiving a task reply (across all running tasks). Defaults to5000
.:on_timeout
- what do to when a task times out. The possible values are::exit
(default) - the process that spawned the tasks exits.:kill_task
- the task that timed out is killed. The value emitted for that task is{:exit, :timeout, element}
, whereelement
is the element it timed out on.
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.supervisor(), Enumerable.t(), (term() -> term()), keyword()) :: Enumerable.t()
Returns a stream that runs the given function
concurrently on each
item in enumerable
.
Each item in enumerable
is passed as argument to the given function fun
and processed by its own task. The tasks will be spawned under the given
supervisor
and linked to the current process, similarly to async_nolink/2
.
See async_stream/6
for discussion and examples.
async_stream_nolink(Supervisor.supervisor(), Enumerable.t(), module(), atom(), [term()], keyword()) :: Enumerable.t()
Returns a stream that runs the given module
, function
, and args
concurrently on each item in enumerable
.
Each item in enumerable
will be prepended to the given args
and processed
by its own task. The tasks will be spawned under the given supervisor
and
will not be linked to the current process, similarly to async_nolink/4
.
See async_stream/6
for discussion, options, and examples.
Returns all children PIDs.
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.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([option()]) :: 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
.:temporary
means the task is never restarted,:transient
means it is restarted if the exit is not:normal
,:shutdown
or{:shutdown, reason}
. A:permanent
restart strategy means it is always restarted. It defaults to:temporary
so tasks aren’t automatically restarted when they complete nor in case of crashes. Note the:async
functions in this module support only:temporary
restarts;: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
;
terminate_child(Supervisor.supervisor(), pid()) :: :ok
Terminates the child with the given pid
.