+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.

Reply via email to