Hi Alexey,
I've done some initial testing of the Servlet 3.0 support. I must stress
that it really is pretty simple testing and I'm only using a limited part
of the API: javax.servlet.ServletRequest.startAsync(),
and javax.servlet.AsyncContext.complete(). I don't think that I am able to
test out the NIO support since I am using Jackson for request content
decoding and request content encoding (AFAICS Jackson does not support NIO).
Anyway, the good news is that basic asynchronous request processing seems
to work. However there is a minor glitch which occurs when requests timeout
(I spotted this while stepping through the code during debugging). When a
request times out (30s by default) the request is recycled causing some of
the internal fields of the request to be nulled out
(e.g. org.glassfish.grizzly.servlet.HttpServletRequestImpl.request). This
causes subsequent uses of the HTTP request to fail with ugly run time
exceptions, for example:
public String getMethod() {
if (request == null) {
throw new IllegalStateException("Null request object");
}
return request.getMethod().getMethodString();
}
Is this correct? I think that it is a little dangerous to recycle the
request as soon as the timeout occurs since there may still be active
references to the request, such as the thread processing the request. The
only way that I can detect if a request has been completed externally (via
a timeout) is by registering an AsyncListener and, even if I did, it is
very cumbersome to avoid race conditions when calling methods like
getMethod(). Am I missing something?
If I am correct and Grizzly needs to be less aggressive when releasing
requests, then how would you implement this? Grizzly would need to know
when the code responsible for processing the request has finished. The only
way to do this is for the application to
invoke javax.servlet.AsyncContext.complete(), but the Servlet 3 Javadoc is
a little unclear as to whether or not I can do this, so I am not sure
whether calling this method after a request has timed out will be portable
or not.
Cheers,
Matt