Task.yield_many

You're seeing just the function yield_many, go back to Task module for more information.
Link to this function

yield_many(tasks, timeout \\ 5000)

View Source

Specs

yield_many([t()], timeout()) :: [{t(), {:ok, term()} | {:exit, term()} | nil}]

Yields to multiple tasks in the given time interval.

This function receives a list of tasks and waits for their replies in the given time interval. It returns a list of two-element tuples, with the task as the first element and the yielded result as the second. The tasks in the returned list will be in the same order as the tasks supplied in the tasks input argument.

Similarly to yield/2, each task's result will be

  • {:ok, term} if the task has successfully reported its result back in the given time interval
  • {:exit, reason} if the task has died
  • nil if the task keeps running past the timeout

A timeout, in milliseconds or :infinity, can be given with a default value of 5000.

Check yield/2 for more information.

Example

Task.yield_many/2 allows developers to spawn multiple tasks and retrieve the results received in a given timeframe. If we combine it with Task.shutdown/2, it allows us to gather those results and cancel the tasks that have not replied in time.

Let's see an example.

tasks =
  for i <- 1..10 do
    Task.async(fn ->
      Process.sleep(i * 1000)
      i
    end)
  end

tasks_with_results = Task.yield_many(tasks, 5000)

results =
  Enum.map(tasks_with_results, fn {task, res} ->
    # Shut down the tasks that did not reply nor exit
    res || Task.shutdown(task, :brutal_kill)
  end)

# Here we are matching only on {:ok, value} and
# ignoring {:exit, _} (crashed tasks) and `nil` (no replies)
for {:ok, value} <- results do
  IO.inspect(value)
end

In the example above, we create tasks that sleep from 1 up to 10 seconds and return the number of seconds they slept for. If you execute the code all at once, you should see 1 up to 5 printed, as those were the tasks that have replied in the given time. All other tasks will have been shut down using the Task.shutdown/2 call.