We have observed a JMS message leak using Seam Remoting to subscribe to a JMS topic,
whereby the list of undelivered topic messages grows indefinitely until the server
ultimately runs out of memory and crashes.
The cause of this seems to be that Seam Remoting requires the web client to manually
unsubscribe from topics in order to properly release system resources. This of course
cannot be guaranteed.
Consider the following scenario:
| * Web client subscribes to a JMS topic using the Seam Remoting Javascript:
| Seam.Remoting.subscribe("topicName", subscriptionCallback);
|
| * On the server, a new org.jboss.seam.remoting.messaging.RemoteSubscriber is created,
which in turn creates a new JMS topic subscriber. The JMS provider will now store any new
topic messages until they have been consumed by the web-client.
|
| * Say the web client navigates to a different page (or simply drops out) and therefore
never calls Seam.Remoting.unsubscribe() - in this situation the RemoteSubscriber never
closes its JMS session and all pending topic messages are queued indefinitely by the JMS
provider, ultimately resulting in the server running out memory (or database space if
persistent messages are used).
|
This problem has been observed on JBossAS 4.2.0.GA with JBossMQ and Seam 1.2.1.GA.
It is very easy to reproduce this problem by simply sending persistent messages to the
remoting topic and then observing the jms_messages table in your database to see the
ever-growing list of messages when the client navigates away from the subcribed page.
I have looked at the Seam remoting source code and it would appear that the problem arises
because the only way RemoteSubscriber.unsubscribe() is ever called is if the web client
javascript code 'remembers' to call it (and afaik there is no way of enforcing
this should the user navigate away etc).
It seems someone else has encountered a similar problem
(
http://www.jboss.org/index.html?module=bb&op=viewtopic&t=92485) which addresses
the multiple-subscription issue, however the proposed workaround does not cater for the
situation where the client simply navigates away, never to be seen by the again and
leaving an open topic subscriber to fill up with messages.
I can think of two possible solutions to this:
| * Have some mechanism that gets notified whenever web sessions are deleted by the
server and release any associated RemoteSubscribers accordingly, however this does not
cater for the scenario where the web session stays valid, but the user has simply
navigated away from the page with the topic subscription.
|
| * Another approach may simply be to have some kind of cleanup thread that periodically
checks all RemoteSubscribers to identify and unsubscribe any which have not had poll()
called on them for a predefined period (say 2 or 3 times the remoting poll timeout defined
in components.xml?). Client code may potentially need to be modified to handle
resubscribing if its subscription has expired (with possible associated loss of messages),
however this would not normally happen as long as the ajax client always commenced a new
long-poll as soon as the last one ended.
|
Perhaps a combination of these two approaches would be the cleanest?
Comments anyone?
Thanks
Scott
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4091888#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...