From 3abc847542605b54b9a601a717c805f79a8dd784 Mon Sep 17 00:00:00 2001 From: Alex Gubarev Date: Wed, 12 Aug 2026 20:24:39 +0300 Subject: [PATCH 1/2] Fix Task.yield_many/2 waits too long or forever when :limit exceeds task count --- lib/elixir/lib/task.ex | 3 ++- lib/elixir/test/elixir/task_test.exs | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/elixir/lib/task.ex b/lib/elixir/lib/task.ex index f67efffac45..44e2d948a27 100644 --- a/lib/elixir/lib/task.ex +++ b/lib/elixir/lib/task.ex @@ -1248,9 +1248,10 @@ defmodule Task do {ref, nil} end) + ref_count = map_size(refs) on_timeout = Keyword.get(opts, :on_timeout, :nothing) timeout = Keyword.get(opts, :timeout, 5_000) - limit = Keyword.get(opts, :limit, map_size(refs)) + limit = min(Keyword.get(opts, :limit, ref_count), ref_count) timeout_ref = make_ref() timer_ref = diff --git a/lib/elixir/test/elixir/task_test.exs b/lib/elixir/test/elixir/task_test.exs index 69b55aea570..5cf1239d805 100644 --- a/lib/elixir/test/elixir/task_test.exs +++ b/lib/elixir/test/elixir/task_test.exs @@ -630,6 +630,21 @@ defmodule TaskTest do [{task2, nil}, {task3, {:exit, :normal}}] end + test "returns once all tasks have replied" do + parent = self() + + pid = + spawn(fn -> + task = Task.async(fn -> :done end) + result = Task.yield_many([task], limit: 2, timeout: :infinity) + send(parent, {self(), result}) + end) + + on_exit(fn -> Process.exit(pid, :kill) end) + + assert_receive {^pid, [{%Task{}, {:ok, :done}}]}, 500 + end + test "returns results from multiple tasks with limit and on timeout" do Process.flag(:trap_exit, true) task1 = Task.async(fn -> Process.sleep(:infinity) end) From 7d4073a33449ca4c8009d516970db0d751de033f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 12 Aug 2026 19:54:50 +0200 Subject: [PATCH 2/2] Apply suggestion from @josevalim --- lib/elixir/test/elixir/task_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/elixir/test/elixir/task_test.exs b/lib/elixir/test/elixir/task_test.exs index 5cf1239d805..1a92f144cfb 100644 --- a/lib/elixir/test/elixir/task_test.exs +++ b/lib/elixir/test/elixir/task_test.exs @@ -630,7 +630,7 @@ defmodule TaskTest do [{task2, nil}, {task3, {:exit, :normal}}] end - test "returns once all tasks have replied" do + test "returns once all tasks have replied below limit" do parent = self() pid =