Question

Possible Duplicate:
What is the Haskell response to Node.js?
How can I watch multiple files/socket to become readable/writable in Haskell?

Is it possible to write a Haskell program that performs IO in a non-blocking way like in nodejs?

For example, i would like to get 10 records from a database that is far away, so I would like to fire 10 requests concurrently, and when the result is available, then return this collection. The IO monad is not going to help, because the monad explicitly serializes the computations with bind. I think the continuation passing style where you pass around the computation you want next have the same problem, again it serializes the computation. I do not want to work with threads, I am looking for another solution. Is this possible?

Was it helpful?

Solution

Haskell threads are exceedingly light weight. What is more, GHCs IO monad uses event driven scheduling much of the time, meaning ordinary Haskell code is like continuation passing style node.js code (only compiled to native code and run with multiple CPUs...)

Your example is trivial

import Control.Concurrent.Async

--given a list of requests
requests :: [IO Foo]

--you can run them concurrently
getRequests :: IO [Foo]
getRequests = mapConcurrently id requests

Control.Concurrent.Async is probably exactly what you are looking for with respect to a library for futures. Haskell should never choke on mere thousands of (ordinary) threads. I haven't ever written code that uses millions of IO threads, but I would guess your only problems would be memory related.

OTHER TIPS

TO flesh out the comments on Control.Concurrent.Async, here is an example using the async package.

import Network.HTTP.Conduit
import Control.Concurrent.Async

main = do
    xs <- mapM (async . simpleHttp) [ "www.stackoverflow.com"
                                    , "www.lwn.net"
                                    , "www.reddit.com/r/linux_gaming"]
    [so,lwn,lg] <- mapM wait xs
    -- parse these how ever you'd like

So in the above we define three HTTP get requests for three different websites, launch those requests asynchronously, and wait for all three to finish before proceeding.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top