Taskmaster v0.2.0 Taskmaster View Source
A set of convenience functions for concurrent, asynchronous tasks, loosely inspired by JavaScript's Promises.
Why?
While Elixir's Task
module provides an API for easy creation of concurrent processes, it does so by blocking the caller process on calls to Task.await/2
or Task.async_stream/3
. However, sometimes it is
beneficial to operate asynchronously, in a manner somewhat similar to JavaScript's Promises - let the work be done in the background and then act on the results when everything is resolved.
Taskmaster
wraps around the built-in Task
module to provide a set of useful functions for doing just that.
Link to this section Summary
Functions
Creates a process, that runs funs
concurrently and sends a message to the caller when all of them either return a value or one of them either crashes or returns an error.
Creates a process, that runs funs
concurrently and when the first one resolves, sends a message to the caller.
Link to this section Types
Specs
options() :: [timeout: non_neg_integer(), link: boolean() | nil]
Link to this section Functions
Specs
Creates a process, that runs funs
concurrently and sends a message to the caller when all of them either return a value or one of them either crashes or returns an error.
Possible messages:
{:all_results, results}
when all thefuns
return a result{:all_error, error}
when either function:- returns an
{:error, reason}
- crashes
- exceeds a
:timeout
option
- returns an
The process created by all/2
by default isn't linked to the caller process. It can be started as a linked process by passing a link: true
option.
Options
:timeout
- a timeout for each function (defaults to 5000):link
- should the started process by linked to the caller (defaults tofalse
)
Example:
iex(1)> Taskmaster.all(
...(1)> [
...(1)> fn ->
...(1)> :one
...(1)> end,
...(1)> fn ->
...(1)> :timer.sleep(50)
...(1)> :two
...(1)> end,
...(1)> fn ->
...(1)> :timer.sleep(200)
...(1)> :three
...(1)> end
...(1)> ],
...(1)> timeout: 1000
...(1)> )
{:ok, #PID<0.216.0>}
iex(2)> flush()
{:all_return_values, [:one, :two, :three]}
:ok
Specs
Creates a process, that runs funs
concurrently and when the first one resolves, sends a message to the caller.
Function resolves either by:
- returning a value, which results in a
{:race_won, value}
message - crashing or returning a
{:error, reason}
tuple, which results in a{:race_interrupted, {:error | :exit, reason}}
message - exceeding a
:timeout
options, which results in a{:race_interrupted, :timeout}
message
The process created by race/2
by default isn't linked to the caller process. It can be started as a linked process by passing a link: true
option.
Options
:timeout
- a timeout for each function (defaults to 5000):link
- should the started process by linked to the caller (defaults tofalse
)
Example:
iex(1)> Taskmaster.race([
...(1)> fn ->
...(1)> :one
...(1)> end,
...(1)> fn ->
...(1)> :timer.sleep(200)
...(1)> :two
...(1)> end,
...(1)> fn ->
...(1)> :timer.sleep(300)
...(1)> :three
...(1)> end
...(1)> ])
{:ok, #PID<0.178.0>}
iex(2)> flush
{:race_won, :one}
:ok