I'm trying to get some of our most-used actions to use chunked transfer encoding in order to speed up overall page load by telling the browser what CSS / JS to get immediately, then the browser can fetch that while the server is hitting the database for the information needed to actually render the page.
This has led me to something that is in spirit similar to:
class ChunkedAction[A](action: Action[A]) extends ActionWrapper(action) {
val preChunk = "<html><head>...js & css references go here for immediate download by the client... "
override def apply(request: Request[A]): Future[Result] = {
Future.successful(Result(
ResponseHeader(200, Map(CONTENT_TYPE -> MimeTypes.HTML, TRANSFER_ENCODING -> CHUNKED, TRAILER -> SET_COOKIE)),
Enumerator(preChunk.getBytes("utf8")) >>> Enumerator.flatten(action(request).map(_.body)) &> Results.chunk,
HttpConnection.KeepAlive))
}
}
(In reality it's a lot more complex since the Enumerator.flatten(action(request)) executes directly and the preChunk therefore doesn't go out immediately, but it gets the point across a lot better than the mess I have in place to get around that + all the error / redirect handling)
Results.chunk() takes an optional Iteratee to produce the Trailer headers. These are crucial, since otherwise we can't set e.g. cookies (flash, session).
Now, the action(request) returns a Future[Result], which has the headers in it. However, that is deep inside the callstack (and likely in a separate thread), and not available when calling Results.chunk().
How can I fish out the headers from the action(request)-result to inject it into the Results.chunk call?