wicketstuff-push, bayeux and the memory leak
November 15th, 2007 by Michael Sparer | Published in Comet, WicketI’ve been fiddling around with reverse-ajax (or comet or pushlets) these days/weeks. You know, that stuff where the webserver keeps an open connection to the client and pushes new events to the client with just the transportation-delay – but no client interference. As described in my recent posts, I decided to use Apache Wicket for my webapp, so I looked around if there’s something in the wicketstuff project that fits my needs. And yes, there is the wicketstuff-push project that offers different implementations of server pushes. Xavier Hanin, one of the men behind Ivy, and Vincent Demay did great effort there to implement a timerbased PushImplementation and also a Cometd-based implementation of a event subscribe/publish mechanism. The latter uses an implementation of the Bayeux-spec and the Dojo-library together with wicketstuff-dojo to subscribe to channels and to process the pushes on client side.
Yesterday I took the time to have a closer look on how the Java implementation of the Bayeux protocol works and found out that each new client that subscribes to a channel gets stored in the Bayeux’s client-HashMap … and stays there. So apparently it is up to the user to remove the clients from there. Otherwise the HashMap would grow towards an OutOfMemoryError, which needed some 400.000 clients on my machine.
So how to get them out? Well it ain’t just that easy to say “on session unbinding I simply remove the client with the corresponding session id” as the client id the Bayeux protocol uses isn’t the http-session id. The client id also changes more frequently, a simple reload of the page is enough to have a new client id. So for my application, I subclassed CometdServlet (over which all request and thus all subscriptions are processed) and made a http-session – bayeux-client-session mapping. This means that I always know which session has which client id, and if the client-id differs, it simply gets removed from the Bayeux-map.
Problem solved
P.S.: Bayeux does the same with channels, so be careful with the amount of channels in your webapp
P.P.S.: Wicket’s first release candidate for version 1.3 is out *thumbs-up*