I don't see a reason why we wouldn't return the same order. You can easily
get the ones you want by `for {task, {:ok, value}} <- result do`. Plus
forcing people to iterate will remind them that they most likely need to
shutdown the other tasks.On Thu, Apr 1, 2021 at 3:57 PM [email protected] < [email protected]> wrote: > > In this sense, yield_many becomes a special case of yield_first where > you want to yield on all given tasks. > > I'm not sure if we would want that, because in yield_many the returned > list will be in the same order as the tasks supplied in the tasks input > argument. > However yield_first to preserve the semantics of "returning as soon it > finishes", maybe we should return the tasks in the order of finish (the > first to complete first in the list). > That makes sense? > > Em quarta-feira, 31 de março de 2021 às 19:35:47 UTC-3, > [email protected] escreveu: > >> +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/c31c31f1-2de8-41a4-a3f3-f5b924c2ea1an%40googlegroups.com > <https://groups.google.com/d/msgid/elixir-lang-core/c31c31f1-2de8-41a4-a3f3-f5b924c2ea1an%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/CAGnRm4Lv2QbjToK-_wYTwVBGEeYS6jeDpajXb9pSqipPpm7a-g%40mail.gmail.com.
