[web-devel] Timing WAI response generation

Michael Snoyman michael at snoyman.com
Fri Feb 4 13:28:56 CET 2011

On Fri, Feb 4, 2011 at 2:18 PM, Neil Mitchell <ndmitchell at gmail.com> wrote:
> Hi,
> I've ported Hoogle to WAI/Warp and it's great - I am very happy.
> The only feature I lost is the ability to time how long a response
> takes to generate/send. For my purposes, I'm not even overly bothered
> whether it's the time taken to generate, or the time taken to send to
> the clients machine, or something somewhere between these two times. I
> came up with a couple of ideas:
> 1) I generate my response with a lazy byte string. I could make the
> final chunk of the lazy bytestring something impure (with
> unsafePerformIO) that writes into an MVar when it gets forced.
> 2) If I knew more about enumerators/iteratees I think it might be
> possible for each chunk generated to start a time, wait til the chunk
> is ready, and then stop the timer - giving the exact time to generate
> all the chunks. Or append two chunks, one at each end, that start/stop
> the timer.
> Does anyone have any better suggestions, or ways of performing the timing?

Depending on how precise you want the answer to be, the easiest
solution is a middleware:

timeMyResponse app req = do
    start <- liftIO getCurrentTime
    res <- app req
    forceEval res
    stop <- liftIO getCurrentTime
    logTime start stop
    return res

The question is what forceEval needs to be. In theory, if you know
you're always using the ResponseBuilder constructor (eg, you only ever
use responseLBS), this could look like:

forceEval (ResponseBuilder b) = return $ L.length $ toLazyByteString b


More information about the web-devel mailing list