+1 for yield_first(tasks, n, timeout) It seems to better convey the meaning "yield the first n tasks".
Em qua., 31 de mar. de 2021 às 19:26, Felipe Stival <[email protected]> escreveu: > +1 for yield_first(tasks, n, timeout) > > > On Thu, Apr 1, 2021, 01:11 José Valim <[email protected]> wrote: > >> It was not possible to implement yield_first in Elixir but now that we >> have map_get in guards, we can easily do so by putting all refs in a map >> and only getting messages from the inbox where the ref is in the map. The >> number of tasks to wait and the maximum timeout should be configurable too. >> For example: >> >> yield_first(task, 3, 1000) >> >> The above will yield the first 3 tasks within 1000ms. It should have the >> same result type as yield_many. In this sense, yield_many becomes a special >> case of yield_first where you want to yield on all given tasks. >> >> Another option is to not introduce a new function but instead introduce a >> new argument to yield_many with the limit to yield: >> >> yield_many(task, 1000, 3) >> >> >> >> On Wed, Mar 31, 2021 at 11:52 PM [email protected] < >> [email protected]> wrote: >> >>> 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 >>> <https://groups.google.com/d/msgid/elixir-lang-core/fe8d048f-605b-4b7a-ad2d-64fb11727d4dn%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/CAGnRm4L%2BogpwDohNaRoZHkT0%3DkOdFROdT37BQJx3k%3D%3DzZqQzAA%40mail.gmail.com >> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4L%2BogpwDohNaRoZHkT0%3DkOdFROdT37BQJx3k%3D%3DzZqQzAA%40mail.gmail.com?utm_medium=email&utm_source=footer> >> . >> > -- > You received this message because you are subscribed to a topic in the > Google Groups "elixir-lang-core" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/elixir-lang-core/ZIFsisK12CM/unsubscribe > . > To unsubscribe from this group and all its topics, send an email to > [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/elixir-lang-core/CAKC64%2BwFh20dRTVnJi5QC8Ekk5CNcSx8k8jW_xBP65rOYGukYw%40mail.gmail.com > <https://groups.google.com/d/msgid/elixir-lang-core/CAKC64%2BwFh20dRTVnJi5QC8Ekk5CNcSx8k8jW_xBP65rOYGukYw%40mail.gmail.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/CANUU5bsMzoPzgcokN%3DF8T%3DX4kZEdXw0w1_R1%3D%2BE-gy5jFAHk7w%40mail.gmail.com.
