mardi 3 août 2010

GraniteDS and the current state of Servlet 3

GraniteDS, and in particular the Gravity comet-like push greatly benefit from the asynchronous capabilities of the servlet containers to get a much better scalability than traditional synchronous servlets. It allows the server to handle long-polling http requests without blocking threads unnecessarily: basically long-polling http requests do nothing most of the time and wait for the server to have something to send.

Asynchronous processing has been supported for a long time on the most popular containers (Tomcat, Jetty, JBossWeb) but the implementations depend on the container-specific APIs (CometProcessor for Tomcat, Continuations for Jetty, HttpEvent for JBossWeb). The Servlet 3 API, approved almost a year ago as part of JEE6, is supposed to bring standardisation to this domain. It's very interesting for Gravity because it means that we could have only one implementation for all containers. Unfortunately the only stable container currently supporting Servlet 3 is GlassFish v3 which is the reference implementation, thus we built our experimental support for Servlet 3 in GraniteDS 2.0 on this server.

There are now a few near-stable containers supporting Servlet 3 and we have made some improvements to our servlet 3 support, so it's interesting to have a look now at how GraniteDS behaves on the following containers :
  • GlassFish v3.0.1 (download here)

  • Tomcat 7 beta (download here)

  • Jetty 8 M1 (download here)

  • JBoss 6 M4 (download here)


Gravity can be configured for Servlet 3 with the following snippet in web.xml :
<servlet>
<servlet-name>GravityServlet</servlet-name>
<servlet-class>org.granite.gravity.servlet3.GravityAsyncServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GravityServlet</servlet-name>
<url-mapping>/gravityamf/*</url-mapping>
</servlet-mapping>


Thanks to the new servlet 3 APIs, it's also possible to simply add a marker class to configure GraniteDS :
@FlexFilter
public class GraniteConfig {
}

In this case, there is nothing to configure in web.xml, and the Gravity servlet will be mapped on /gravityamf/* by default.

The good news is that the GraniteDS examples (in particular the chat) all work correctly on these containers with this Servlet 3 support. But of course there are a few issues that I'm going to detail.

Tomcat 7 beta

Even if it was functioning relatively correctly, the CometProcessor API in Tomcat 6 was sort of a hack and had lots of issues. It seems to be better with Servlet 3 on Tomcat 7 but there are still problems.
Tomcat requires either a NIO connector or the APR native library to handle asynchronous servlets, and these connectors have quite different behaviours with GDS 2.1.0.GA. None seems to lose messages or drop requests though, but APR triggers lots of strange NullPointerExceptions. We do not know yet if the problem comes from Tomcat or from Gravity (GDS-703).

JBoss 6 M4

Support of Servlet 3 in JBossWeb has been added since JBoss 6 M2. It works much better that Tomcat 7, but there are occasional IllegalStateExceptions that maybe come from Gravity. Notice that you will also need a NIO connector or the APR native library (JBossWeb is more or less a modified Tomcat).
Also note that due to this bug, support for asynchronous servlets will not work with CDI.

Jetty 8 M1

As always with Jetty, everything seems to work just fine without too much hassle. Just download, install and start. We have not found any particular issue yet with GDS 2.1.0.GA.

GlassFish v3.0.1

No big issue detected until now. We have not conducted extensive testing, but Servlet 3 support can be considered stable. Of course for production use, you should run your own stress tests depending on your application.

It's nice to see JEE6 taking shape in the open source space and hopefully all these containers will be released before the end of the year. Support in WebLogic or WebSphere seems a lot more distant, but who knows.

Aucun commentaire: