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);
         }