You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sk...@apache.org on 2009/02/22 16:46:37 UTC
svn commit: r746741 -
/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java
Author: skitching
Date: Sun Feb 22 15:46:37 2009
New Revision: 746741
URL: http://svn.apache.org/viewvc?rev=746741&view=rev
Log:
Fix Orchestra-35 : In some containers (eg OC4J), ConversationManager is not removed from ConversationWiperThread on session timeout. Thanks to Steve Ronderos for the bugreport.
Modified:
myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java
Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java?rev=746741&r1=746740&r2=746741&view=diff
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/servlet/ConversationManagerSessionListener.java Sun Feb 22 15:46:37 2009
@@ -32,6 +32,7 @@
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
/**
* An http session listener which periodically scans every http session for
@@ -64,7 +65,11 @@
// SessionListener as it also implements ServletContextListener. This class specifically
// handles ConversationWiperThread issues...
public class ConversationManagerSessionListener
- implements HttpSessionAttributeListener, HttpSessionActivationListener, ServletContextListener
+ implements
+ ServletContextListener,
+ HttpSessionListener,
+ HttpSessionAttributeListener,
+ HttpSessionActivationListener
{
private final Log log = LogFactory.getLog(ConversationManagerSessionListener.class);
private final static long DEFAULT_CHECK_TIME = 5 * 60 * 1000; // every 5 min
@@ -111,6 +116,40 @@
}
+ public void sessionCreated(HttpSessionEvent event)
+ {
+ // Nothing to do here
+ }
+
+ public void sessionDestroyed(HttpSessionEvent event)
+ {
+ // If the session contains a ConversationManager, then remove it from the WiperThread.
+ //
+ // Note that for most containers, when a session is destroyed then attributeRemoved(x)
+ // is called for each attribute in the session after this method is called. But some
+ // containers (including OC4J) do not; it is therefore best to handle cleanup of the
+ // ConversationWiperThread in both ways..
+ //
+ // Note that this method is called *before* the session is destroyed, ie the session is
+ // still valid at this time.
+
+ HttpSession session = event.getSession();
+ Enumeration e = session.getAttributeNames();
+ while (e.hasMoreElements())
+ {
+ String attrName = (String) e.nextElement();
+ Object o = session.getAttribute(attrName);
+ if (o instanceof ConversationManager)
+ {
+ // This call will trigger method "attributeRemoved" below, which will clean up the wiper thread.
+ // And because the attribute is removed, the post-destroy calls to attributeRemoved will then
+ // NOT include this (removed) attribute, so multiple attempts to clean it up will not occur.
+ log.debug("Session containing a ConversationManager has been destroyed (eg timed out)");
+ session.removeAttribute(attrName);
+ }
+ }
+ }
+
public void attributeAdded(HttpSessionBindingEvent event)
{
// Somebody has called session.setAttribute
@@ -124,12 +163,13 @@
public void attributeRemoved(HttpSessionBindingEvent event)
{
// Either someone has called session.removeAttribute, or the session has been invalidated.
- // When an HttpSession is invalidated (including when it "times out"), this method is
- // called once for every attribute in the session; note however that at that time the
- // session is invalid so in some containers certain methods (including getId and
- // getAttribute) throw IllegalStateException.
+ // When an HttpSession is invalidated (including when it "times out"), first SessionDestroyed
+ // is called, and then this method is called once for every attribute in the session; note
+ // however that at that time the session is invalid so in some containers certain methods
+ // (including getId and getAttribute) throw IllegalStateException.
if (event.getValue() instanceof ConversationManager)
{
+ log.debug("A ConversationManager instance has been removed from a session");
ConversationManager cm = (ConversationManager) event.getValue();
conversationWiperThread.removeConversationManager(cm);
}