[Haskell-cafe] Help with async library and killing child processes

Patrick Chilton chpatrick at gmail.com
Fri Mar 20 03:01:04 UTC 2020


>
> Is there a way to get the result of "either of three calls to getUrl" as
> opposed to "all three calls"?
> 'Cause that's what Mike seems to want.


That's what the Alternative instance of Concurrently is for. The result of
`doA <|> doB` is the result of the argument that finished first. (<|>) =
race.

firstResult <- runConcurrently (Concurrently (getURL "url1") <|>
Concurrently (getURL "url2") <|> Concurrently (getURL "url3"))

or

firstResult <- runConcurrently $ asum $ map (Concurrently . getURL) [
"url1", "url2", "url3" ]

On Fri, Mar 20, 2020 at 9:44 AM Artem Pelenitsyn <a.pelenitsyn at gmail.com>
wrote:

> Hey Niklas,
>
> Thanks for your explanation -- it was useful to read.
>
> Is there a way to get the result of "either of three calls to getUrl" as
> opposed to "all three calls"?
> 'Cause that's what Mike seems to want.
>
> --
> Best regards,
> Artem
>
>
> On Thu, 19 Mar 2020 at 21:38, Niklas Hamb├╝chen <mail at nh2.me> wrote:
>
>> Hey Mike,
>>
>> >     f <- async getPages
>> >     cancel f
>>
>> you haven't read the PR I linked carefully enough yet :)
>>
>> It essentially says to never use the `async` function, as that is almost
>> never what you want
>>
>> Full docs, with what you need to read highlighted:
>>
>> https://github.com/nh2/async/blob/1d96dc555b70a4c5aba07f15d0c7895545eb8582/Control/Concurrent/Async.hs#L21-L143
>>
>> > Am I guaranteed the the getURL() calls will definitely have either
>> finished, or cancel?
>>
>> For
>>
>>     do
>>       (page1, page2, page3) <- runConcurrently $
>>         (,,)
>>           <$> Concurrently (getURL "url1")
>>           <*> Concurrently (getURL "url2")
>>           <*> Concurrently (getURL "url3")
>>
>> you are guaranteed that when `runConcurrently` returns, all 3 downloads
>> have finished successfully.
>>
>> Only the `instance Alternative Concurrently` (that is, when you use <|>)
>> is implemented in terms of `race`.
>>
>> You are using <*>, as implemented in the `instance Applicative
>> Concurrently`, which uses `concurrently`, which waits for both of two
>> actions.
>>
>> Your code in
>>
>> > main = do
>> >     f <- async getPages
>> >     cancel f
>>
>> does not make much sense:
>> Here you're starting a thread that would go off do something, but then
>> you immediately cancel that thread, so it won't achieve anything.
>>
>> You do not need to wrap things into additional `async`s. You can directly
>> do, for example:
>>
>>     main :: IO ()
>>     main = do
>>       (page1, page2, page3) <- runConcurrently $
>>         (,,)
>>           <$> Concurrently (getURL "url1")
>>           <*> Concurrently (getURL "url2")
>>           <*> Concurrently (getURL "url3")
>>       putStrLn "Here are the page contents:"
>>       putStrLn page1
>>       putStrLn page2
>>       putStrLn page3
>>
>> Hope that helps!
>>
>> Niklas
>> _______________________________________________
>> Haskell-Cafe mailing list
>> To (un)subscribe, modify options or view archives go to:
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>> Only members subscribed via the mailman list are allowed to post.
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20200320/924ad363/attachment.html>


More information about the Haskell-Cafe mailing list