Tasks
Mix.install([
{:kino, "~> 0.6.2"},
{:factory, path: "./factory"}
])
Navigation
Tasks
Tasks generally behave as expected from within livebook.
task =
Task.async(fn ->
Process.sleep(1000)
"result"
end)
Task.await(task) |> IO.puts()
IO.puts("Execution is paused until task finishes")
task =
Task.async(fn ->
Process.sleep(7000)
"result"
end)
Task.await(task)
task =
Task.async(fn ->
Process.sleep(7000)
"result"
end)
Task.yield(task) |> IO.inspect(label: "yield after 5 second timeout")
Task.yield(task) |> IO.inspect(label: "yield after 7 seconds.")
Supervised Tasks
children = [
{Task.Supervisor, name: :task_supervisor}
]
Supervisor.start_link(children, strategy: :one_for_one)
We can start tasks under a supervisor and see them as a list of children pids
Task.Supervisor.async(:task_supervisor, fn ->
Process.sleep(10000)
end)
Task.Supervisor.children(:task_supervisor)
Visualizing tasks under the :task_supervisor
.
Kino.animate(500, 0, fn _ ->
tree = Kino.Process.sup_tree(:task_supervisor)
{:cont, tree, 0}
end)
Linked tasks cause the parent process to crash when we terminate_child/2
.
task =
Task.Supervisor.async_nolink(:task_supervisor, fn ->
Process.sleep(20000)
end)
Task.shutdown(task)
pid = :c.pid(0, 522, 0)
Task.Supervisor.terminate_child(:task_supervisor, pid)
Visualizing Task Clusters
# Kino.animate(500, 0, fn _ ->
# tree = Kino.Process.sup_tree(:task_supervisor)
# {:cont, tree, 0}
# end)
# tasks =
# Enum.map(1..10, fn i ->
# Task.Supervisor.async(:task_supervisor, fn ->
# Process.sleep(11000 - i * 1000)
# i
# end)
# end)
# Task.await_many(tasks, 11000)
Key Takeaways (Conclusion)
You can use LiveBook to:
- Gain insight into OTP processes or alongside an existing application.
- Quickly develop OTP experiments and save examples for yourself in the future.
- Document projects or teach other developers.