[seam-commits] Seam SVN: r9712 - in trunk/src/main/org/jboss/seam: jmx and 1 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Thu Dec 4 02:22:51 EST 2008


Author: dan.j.allen
Date: 2008-12-04 02:22:51 -0500 (Thu, 04 Dec 2008)
New Revision: 9712

Added:
   trunk/src/main/org/jboss/seam/jmx/
   trunk/src/main/org/jboss/seam/jmx/JBossClusterMonitor.java
Modified:
   trunk/src/main/org/jboss/seam/servlet/SeamListener.java
Log:
JBSEAM-3172

Added: trunk/src/main/org/jboss/seam/jmx/JBossClusterMonitor.java
===================================================================
--- trunk/src/main/org/jboss/seam/jmx/JBossClusterMonitor.java	                        (rev 0)
+++ trunk/src/main/org/jboss/seam/jmx/JBossClusterMonitor.java	2008-12-04 07:22:51 UTC (rev 9712)
@@ -0,0 +1,149 @@
+package org.jboss.seam.jmx;
+
+import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.servlet.ServletContext;
+
+import org.jboss.seam.Seam;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Startup;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+
+ at Name("org.jboss.seam.jmx.jbossClusterMonitor")
+ at BypassInterceptors
+ at Scope(APPLICATION)
+ at Startup
+ at Install(precedence=BUILT_IN, classDependencies="org.jgroups.MembershipListener")
+public class JBossClusterMonitor
+{
+   private static Log log = Logging.getLog(JBossClusterMonitor.class);
+   
+   private MBeanServer jbossMBeanServer;
+   
+   private boolean clustered;
+   
+   private ObjectName clusteringCacheObjectName;
+   
+   private ObjectName serverObjectName;
+   
+   @Create
+   public void create()
+   {
+      jbossMBeanServer = locateJBoss();
+      
+      if (!isJBoss())
+      {
+         return;
+      }
+      
+      try
+      {
+         clusteringCacheObjectName = new ObjectName("jboss.cache:service=TomcatClusteringCache");
+         serverObjectName = new ObjectName("jboss.system:type=Server");
+      }
+      catch (MalformedObjectNameException e)
+      {
+         log.warn("Invalid JMX name: " + e.getMessage());
+      }
+      
+      try
+      {
+         jbossMBeanServer.getMBeanInfo(clusteringCacheObjectName);
+         clustered = true;
+         log.info("JBoss cluster detected");
+      }
+      catch (Exception e) {}
+   }
+   
+   public boolean isClustered()
+   {
+      return clustered;
+   }
+   
+   /**
+    * Consults the jboss.system:type=Server MBean to determine if this instance
+    * of JBoss AS is currently being shutdown. Note that the flag only returns
+    * true if the shutdown() method on this MBean is used. It does not detect a
+    * force halt via a process signal (i.e., CTRL-C).
+    */
+   public boolean nodeIsShuttingDown()
+   {
+      if (!isJBoss())
+      {
+         return false;
+      }
+      
+      try
+      {
+         return (Boolean) jbossMBeanServer.getAttribute(serverObjectName, "InShutdown");
+      }
+      catch (Exception e)
+      {
+         return false;
+      }
+   }
+   
+   public boolean isLastNode()
+   {
+      if (!clustered)
+      {
+         return true;
+      }
+      
+      // other options
+      // object name => jboss.jgroups:cluster=DefaultPartition,type=channel
+      // object name => jboss.jgroups:cluster=Tomcat-Cluster,type=channel
+      // attribute => NumberOfTasksInTimer
+      
+      try
+      {
+         return ((Vector) jbossMBeanServer.getAttribute(clusteringCacheObjectName, "Members")).size() == 1;
+      }
+      catch (Exception e) {
+         log.warn("Could not determine number of members in cluster", e);
+         return true;
+      }
+   }
+   
+   public boolean failover()
+   {
+      return isClustered() && nodeIsShuttingDown() && !isLastNode();
+   }
+   
+   public boolean isJBoss()
+   {
+      return jbossMBeanServer != null;
+   }
+   
+   protected MBeanServer locateJBoss()
+   {
+      for (Iterator i = MBeanServerFactory.findMBeanServer(null).iterator(); i.hasNext(); )
+      {
+         MBeanServer server = (MBeanServer) i.next();
+         if (server.getDefaultDomain().equals("jboss"))
+         {
+            return server;
+         }
+      }
+      return null;
+   }
+   
+   // FIXME my sense is that this could lookup could be more elegant or conforming
+   public static JBossClusterMonitor getInstance(ServletContext ctx)
+   {
+      return (JBossClusterMonitor) ctx.getAttribute(Seam.getComponentName(JBossClusterMonitor.class));
+   }
+}

Modified: trunk/src/main/org/jboss/seam/servlet/SeamListener.java
===================================================================
--- trunk/src/main/org/jboss/seam/servlet/SeamListener.java	2008-12-04 03:42:05 UTC (rev 9711)
+++ trunk/src/main/org/jboss/seam/servlet/SeamListener.java	2008-12-04 07:22:51 UTC (rev 9712)
@@ -14,6 +14,7 @@
 import org.jboss.seam.Seam;
 import org.jboss.seam.contexts.ServletLifecycle;
 import org.jboss.seam.init.Initialization;
+import org.jboss.seam.jmx.JBossClusterMonitor;
 import org.jboss.seam.log.LogProvider;
 import org.jboss.seam.log.Logging;
 
@@ -46,7 +47,16 @@
    
    public void sessionDestroyed(HttpSessionEvent event) 
    {
-      ServletLifecycle.endSession( event.getSession() );
+      JBossClusterMonitor monitor = JBossClusterMonitor.getInstance(event.getSession().getServletContext());
+      if (monitor != null && monitor.failover())
+      {
+         // If application is unfarmed or all nodes shutdown simultaneously, cluster cache may still fail to retrieve SFSBs to destroy
+         log.info("Detected fail-over, not destroying session context");
+      }
+      else
+      {
+         ServletLifecycle.endSession( event.getSession() );
+      }
    }
    
 }




More information about the seam-commits mailing list