Elixir Distributed Tasks
A distributed task is work run under a task supervisor that can live on another node. This lesson proves the supervisor mechanics on one node, since a real cluster is needed to prove work on another node.
A task supervisor runs a task
Task.Supervisor.async() starts work under a supervisor and returns a task. Task.await() collects its result.
{:ok, sup} = Task.Supervisor.start_link()
task = Task.Supervisor.async(sup, fn -> 6 * 7 end)
IO.inspect(Task.await(task))
Supervisor.stop(sup)A supervisor can run several tasks at once
Two tasks can run under one supervisor. Awaiting both and adding the results gives 40.
{:ok, sup} = Task.Supervisor.start_link()
first = Task.Supervisor.async(sup, fn -> 10 + 5 end)
second = Task.Supervisor.async(sup, fn -> 20 + 5 end)
IO.inspect(Task.await(first) + Task.await(second))
Supervisor.stop(sup)A stream of tasks keeps its order
Task.Supervisor.async_stream() runs one task per item. Unwrapping each result keeps the values in item order.
{:ok, sup} = Task.Supervisor.start_link()
results = Task.Supervisor.async_stream(sup, [2, 3, 4], fn x -> x * 100 end) |> Enum.map(fn {:ok, value} -> value end)
IO.inspect(results)
Supervisor.stop(sup)Example
{:ok, sup} = Task.Supervisor.start_link()
doubled = Task.Supervisor.async_stream(sup, [2, 3, 4], fn x -> x * 100 end) |> Enum.map(fn {:ok, value} -> value end)
IO.inspect(doubled)
IO.inspect(Enum.sum(doubled))
Supervisor.stop(sup)Key points
- Task.Supervisor: a supervisor that starts and watches tasks.
- Task.Supervisor.async(): starts one task under a supervisor and returns a task.
- Task.await(): collects a task's result.
- Task.Supervisor.async_stream(): runs one task per item and keeps the results in order.
- Stop: Supervisor.stop() stops the supervisor when the work is done.
In this example, the script starts a task supervisor, runs one task per item to scale each number by 100, prints the scaled values in order, and prints their sum. The supervisor is stopped at the end.
Note
in a real cluster the supervisor is addressed by name and node, and this lesson proves only the local mechanics on one node.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does Task.await() return for a task that computes 6 * 7?