I think the proposal would work differently from yield_many. yield_many "receives a list of tasks and waits for their replies in the given time interval". The proposal of the new function is to return as soon as the first task finishes.
For example, if we start tasks to make call to 3 different remote APIs, with different response times. API A - 50ms API B - 500ms API C - 1500ms tasks = [ Task.async(&api_a/0), Task.async(&api_b/0), Task.async(&api_c/0) ] # returns result of API A and API B waiting for 1000ms Task.yield_many(tasks, 1000) With run using `yield_many` we would wait for the 1000ms and get the responses of API A and API B. The proposal of the new function is to return as soon as we get a response. Using the same example of the 3 calls, we would wait only for 50ms (as soon as the first task finishes) and return the result of the first task finishing, without waiting for the other call. tasks = [ Task.async(&api_a/0), Task.async(&api_b/0), Task.async(&api_c/0) ] # returns only result of API A waiting for 50ms Task.proposed_function(tasks) Em quarta-feira, 31 de março de 2021 às 18:06:47 UTC-3, [email protected] escreveu: > Check out Task.yield_many/2 ( > https://hexdocs.pm/elixir/Task.html#yield_many/2) :-) > > On 31 Mar 2021, at 22:54, [email protected] <[email protected]> > wrote: > > *Proposal* > > Add a function to the Task module that takes a list of tasks, and returns > as soon as one of the tasks finishes, shuting down the other tasks. > The behaviour would pretty similar to what Javascript have with > Promise.any > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any > > *Motivation* > > One scenario that it could be useful is when we are integrating with > multiple APIs (providers) of the same data, and we want only the fastest > result without needing to wait for the other requests to complete. > > Today I think this could be implemented with something similar to the > following code: > > tasks = [ > Task.async(&heavy_fun_1/0), > Task.async(&heavy_fun_2/0), > Task.async(&heavy_fun_3/0) > ] > > receive do > {ref, result} -> > tasks > |> Enum.reject(fn task -> task.ref == ref end) > |> Enum.each(&Task.shutdown/1) > > result > after > 5000 -> > {:error, :timeout} > end > > However that seems to be a common enough pattern to add to the standard > library. > > *Questions* > > - Am I missing something here and this could already be easily > accomplished with the existing API? > - What should be the behaviour when the first task to complete exits? > > -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/elixir-lang-core/59a5b5af-528b-4f1f-8e17-6dad9edfe9ccn%40googlegroups.com > > <https://groups.google.com/d/msgid/elixir-lang-core/59a5b5af-528b-4f1f-8e17-6dad9edfe9ccn%40googlegroups.com?utm_medium=email&utm_source=footer> > . > > > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/fe8d048f-605b-4b7a-ad2d-64fb11727d4dn%40googlegroups.com.
