Task (Elixir)
Elixir Tasks
Creating Tasks
Tasks can be started either with an anonymous function or using the Module-Function-Arguments (MFA) form.
Handling Timeouts with receive
A plain receive waits forever if no matching message arrives.
Use an after clause to avoid blocking indefinitely (this is basically a
timeout in Erlang).
receive do
{^pid, :result, value} ->
value
after
2000 ->
raise "Timed out!"
end
- Prevents hanging when a process crashes or takes too long.
- Timeout is specified in milliseconds.
Task.await/2
- Default timeout: 5 seconds
- Raises an exception if the task doesn't finish in time.
Task.await(task)
# default: 5000 ms
Task.await(task, 7000)
# custom timeout
Task.await(task, :infinity)
# wait forever
Task.yield/2
Unlike `Task.await`, `Task.yield` lets you poll a task without crashing on timeout.
Returns:
- `{:ok, result}` → task completed
- `nil` → timeout expired
case Task.yield(task, 5000) do
{:ok, result} ->
result
nil ->
Logger.warn("Timed out!")
Task.shutdown(task)
end
Useful for:
- Long-running background work.
- Periodically checking task completion.
- Gracefully shutting down stalled tasks.
Task.shutdown/1
Stops a running task.
- Returns `{:ok, result}` if the task finishes while shutting down.
- Returns `nil` if it doesn't.
Often used together with `Task.yield`.
Human-Friendly Time Values
Instead of hardcoding milliseconds, use Erlang's :timer helpers.
:timer.seconds(5) ;; 5000
:timer.minutes(5) ;; 300000
:timer.hours(5) ;; 18000000
Task.await(task, :timer.seconds(7))
This makes timeout values easier to read and maintain.