Ed,
I agree with the basic outline of how you see the push mechanism working -
assuming I understand JSF enough.
The paraphrase what you are saying, the framework generates a response
against a context that collects associated resource. Once the page is
rendered, then the associated resources are pushed with:
if (isHttp2) {
handler.pushResources(context);
}
So firstly I think we should avoid the need for isHttp2 style
conditional. Push should just be a noop if it is not supported. However
I guess we need isPushSupported for those frameworks that might go to a lot
of effort to work out what resources to push - so they don't waste that
effort.
However, I'm concerned that pushing resources after rendering the primary
resource will be too late. If it is a large HTML document, the client is
going to be parsing it as it is received and firing off requests for
associated resources long before the HTML document has completed being sent.
So I think the resources should be pushed as soon as they are discovered -
with some obvious protection against duplicate pushes.
So the context could have a method:
context.addAssociatedResource(String uriInContext)
{
associated.add(uriInContext);
ConcurrentSet<String> pushed =
getRequest().getHttpSession().getAttribute("pushed);
if (pushed.addIfAbsent(uriInContext))
getServletContext().getRequestDispatcher(
uriInContext).push(getRequest())
}
that would trigger a push as the associated resource is first added to the
context, using the API that I have proposed.
Note that the API I have proposed does not actually do the pushing. It
dispatches a new request to the container on a new thread, exactly as if
the a real request had arrived. This can be served in parallel to the
original request using whatever IO techniques the target servlet wishes to
use.
The pushed resource needs to be generated in another thread dispatched to
the container as it may complete before or after the primary resource.
Specifically the browser might send priority messages or even use flow
control to favour one stream over the other, so the pushed resource may
allowed to run to completion while the main resource is blocked/throttled,
OR the browser could decide the main resource is more important and
throttle the pushed resource.
So your pushResources method would not work, as it does not allow the
browser to control the order/priority/flow control of the pushed
resources. Serving pushed resources cannot be done serially.
maybe my proposed method should be called schedulePush or dispatchPush to
make it clear that the push is not done within the scope of the call to
push?
cheers
--
Greg Wilkins <gregw_at_intalio.com>
http://eclipse.org/jetty HTTP, SPDY, Websocket server and client that scales
http://www.webtide.com advice and support for jetty and cometd.