0
votes

I run supervised tasks via async_nolink and at the end await for multiple results with Task.yield_many - example code:

request =
    1..10
    |> Enum.map fn x ->
       result = Task.Supervisor.async_nolink(Final.TaskSupervisor, fn ->
         res = case x do
                 2 -> x + "abc"
                 _ -> x + x

               end
         end)
        end

    results = Task.yield_many(request, 5000)

Now when task called by "2" crashes, how can I identify the number? Or in real-world, that would be event that started the task(domain name in my case).

I wrote long reduce code that saves tasks in one list, tuples of task.ref and identifier(domain name) in another. Then I am combining this tasks with another group of tasks and after yield_many cross comparing again... Seems way too messy for beautiful language like elixir :)

Am I missing some simpler alternative ?

1

1 Answers

0
votes

I would zip the original data with Task.yield_many(tasks) since the results of Task.yield_many are in the same order as the list of tasks:

Task.Supervisor.start_link name: MyApp.TaskSupervisor

data = 1..10

tasks = for x <- data do
  Task.Supervisor.async_nolink(MyApp.TaskSupervisor, fn ->
    case x do
      2 -> x + "abc"
      4 -> raise "I don't like 4!"
      _ -> x + x
    end
  end)
end

for {datum, {_task, result}} <- Enum.zip(data, Task.yield_many(tasks)) do
  IO.puts "#{datum} => #{inspect(result)}"
end

Output (excluding the crash messages):

1 => {:ok, 2}
2 => {:exit, {:badarith, [{:elixir_compiler_0, :"-__FILE__/1-fun-0-", 1, [file: 'a.exs', line: 8]}, {Task.Supervised, :do_apply, 2, [file: 'lib/task/supervised.ex', line: 94]}, {Task.Supervised, :reply, 5, [file: 'lib/task/supervised.ex', line: 45]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]}}
3 => {:ok, 6}
4 => {:exit, {%RuntimeError{message: "I don't like 4!"}, [{:elixir_compiler_0, :"-__FILE__/1-fun-0-", 1, [file: 'a.exs', line: 9]}, {Task.Supervised, :do_apply, 2, [file: 'lib/task/supervised.ex', line: 94]}, {Task.Supervised, :reply, 5, [file: 'lib/task/supervised.ex', line: 45]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]}}
5 => {:ok, 10}
6 => {:ok, 12}
7 => {:ok, 14}
8 => {:ok, 16}
9 => {:ok, 18}
10 => {:ok, 20}