Adrian May
Adrian May

Reputation: 2182

Long polling in Yesod

Can I do long polling in Yesod, or any other Haskell web framework with comparable database facilities?

To be precise, I want to delay a HTTP response until something interesting happens. There should also be a timeout after which the client will be served a response saying "nothing happened" and then the client will issue the same request.

To make life even more complicated, the app I have in mind is serving all its stuff over both HTTP/HTML5 and a really compact UDP protocol to MIDP clients. Events from either protocol can release responses in either protocol.

TIA, Adrian.

Upvotes: 8

Views: 830

Answers (2)

Michael Snoyman
Michael Snoyman

Reputation: 31345

I can't answer all the issues of the more complicated UDP stuff, but the short answer is that, yes, Yesod supports long polling. You can essentially do something like:

myHandler = do
    mres <- timeout timeoutInMicroseconds someAction
    case mres of
        Nothing -> return nothingHappenedResponse
        Just res -> doSomething res

You'll probably want to used System.Timeout.Lifted from the lifted-base package.

Upvotes: 7

Dave Turner
Dave Turner

Reputation: 1896

Michael's answer hits the timeout requirement. For general clients you do not want to keep HTTP responses waiting for more than about 60 seconds as they may be connecting through a proxy or similar which tend to get impatient after about that long. If you're on a more tightly controlled network then you may be able to relax this timeout. One minor correction is that the parameter to timeout is in microseconds not nanoseconds.

For the 'wait for something interesting to happen' part, we use the check combinator from Control.Concurrent.STM (which wraps up retry) so our handler thread waits on a TVar:

someAction = do
    interestingStuff <- atomically $ do
        currentStuff <- readTVar theStuff
        check $ isInteresting currentStuff
        return currentStuff
    respondWith interestingStuff

Meanwhile, other threads (incl HTTP handlers) are updating theStuff :: TVar Stuff - each update triggers a new calculation of isInteresting and potentially a response if it returns True.

This is compatible with serving the same information over UDP: simply share theStuff between your UDP server threads and the Yesod threads.

Upvotes: 4

Related Questions