PRs to improve the docs is always welcome!

On Fri, Apr 2, 2021 at 21:02 thia.md...@gmail.com <thia.mdossan...@gmail.com>
wrote:

> > And this made me wonder: is there any reason why you can't use
> Task.async_stream?
>
> After testing, I'm sure we can accomplish the same thing that was proposed
> with Task.async_stream. There is really no reason for an extra function.
>
> One thing that would be nice is to have an example for this usage in the
> documentation. I honestly never thought in using Task.async_stream in this
> way.
>
> WDYT? PRs for adding this example to the documentation would be welcome?
>
> Em sexta-feira, 2 de abril de 2021 às 08:39:18 UTC-3, emt...@gmail.com
> escreveu:
>
>> Funny that exactly on this day that the proposal was opened I said in two
>> groups the lack that I was doing something similar to "Promise.any" in
>> Elixir.
>>
>> I needed it and found it complicated to do now, I had a job because I'm
>> starting in Elixir.
>>
>> I would love to have another solution for what I did, when researching
>> several APIs to return the CEP query to me and get the first valid result.
>>
>> I'm starting in Elixir and in love, and I made my first package with
>> exactly this need:
>> https://github.com/ciareis/cep-promise-elixir/blob/master/lib/cep_promise.ex#L52
>>
>> I could probably write everything in a better way, but I still get there.
>>
>> Please implement something to facilitate this;)
>>
>> Elixir S2!
>> Em sexta-feira, 2 de abril de 2021 às 04:51:53 UTC-3, José Valim escreveu:
>>
>>> I have been thinking more about this problem and there is still one
>>> issue for us to solve: when you say you are waiting for "n" tasks, does it
>>> mean you are waiting for "n" successes or "n" results (regardless if they
>>> are success or failure)?
>>>
>>> So I thought perhaps a better solution is to introduce something called
>>> Task.yield_stream/2. "yield_stream" receives an enumerable of tasks and
>>> emits them as they complete. To get the first successful task you would do:
>>>
>>>     tasks
>>>     |> Task.yield_stream(ordered: false, timeout: 5000)
>>>     |> Stream.filter(&match?({:ok, _}))
>>>     |> Enum.at(0)
>>>
>>> And this made me wonder: is there any reason why you can't use
>>> Task.async_stream?
>>>
>>>
>>> On Thu, Apr 1, 2021 at 3:59 PM José Valim <jose....@dashbit.co> wrote:
>>>
>>>> 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 thia.md...@gmail.com <
>>>> thia.md...@gmail.com> 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,
>>>>> thia.md...@gmail.com 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 <v0i...@gmail.com>
>>>>>> escreveu:
>>>>>>
>>>>>>> +1 for yield_first(tasks, n, timeout)
>>>>>>>
>>>>>>>
>>>>>>> On Thu, Apr 1, 2021, 01:11 José Valim <jose....@dashbit.co> 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 thia.md...@gmail.com <
>>>>>>>> thia.md...@gmail.com> 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,
>>>>>>>>> woj...@wojtekmach.pl escreveu:
>>>>>>>>>
>>>>>>>>>> Check out Task.yield_many/2 (
>>>>>>>>>> https://hexdocs.pm/elixir/Task.html#yield_many/2) :-)
>>>>>>>>>>
>>>>>>>>>> On 31 Mar 2021, at 22:54, thia.md...@gmail.com <
>>>>>>>>>> thia.md...@gmail.com> 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 elixir-lang-co...@googlegroups.com.
>>>>>>>>>> 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 elixir-lang-co...@googlegroups.com.
>>>>>>>>> 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 elixir-lang-co...@googlegroups.com.
>>>>>>>> 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
>>>>>>> elixir-lang-co...@googlegroups.com.
>>>>>>> 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 elixir-lang-co...@googlegroups.com.
>>>>> 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 elixir-lang-core+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/8ef87d9d-32d3-4202-9f4f-d67434d207d1n%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/8ef87d9d-32d3-4202-9f4f-d67434d207d1n%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 elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4LVS2oexZNnKt0CZHtDtiv%2BXhwycANvrZNex3L0xt_%3Dww%40mail.gmail.com.

Reply via email to