[jboss-cvs] JBoss Messaging SVN: r3964 - in branches/Branch_JBossMessaging_1_4_0_SP3_CP: src/main/org/jboss/jms/server/connectionmanager and 1 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Mar 27 13:51:04 EDT 2008


Author: timfox
Date: 2008-03-27 13:51:04 -0400 (Thu, 27 Mar 2008)
New Revision: 3964

Modified:
   branches/Branch_JBossMessaging_1_4_0_SP3_CP/src/main/org/jboss/jms/server/ConnectionManager.java
   branches/Branch_JBossMessaging_1_4_0_SP3_CP/src/main/org/jboss/jms/server/connectionmanager/SimpleConnectionManager.java
   branches/Branch_JBossMessaging_1_4_0_SP3_CP/tests/src/org/jboss/test/messaging/jms/server/connectionmanager/SimpleConnectionManagerTest.java
Log:
http://jira.jboss.org/jira/browse/JBMESSAGING-1262


Modified: branches/Branch_JBossMessaging_1_4_0_SP3_CP/src/main/org/jboss/jms/server/ConnectionManager.java
===================================================================
--- branches/Branch_JBossMessaging_1_4_0_SP3_CP/src/main/org/jboss/jms/server/ConnectionManager.java	2008-03-27 14:19:11 UTC (rev 3963)
+++ branches/Branch_JBossMessaging_1_4_0_SP3_CP/src/main/org/jboss/jms/server/ConnectionManager.java	2008-03-27 17:51:04 UTC (rev 3964)
@@ -66,12 +66,7 @@
    void unregisterConnectionFactoryCallback(String JVMID, String remotingSessionID);
    
 
-   /**
-    * @param clientToServer - true if the failure has been detected on a direct connection from
-    *        client to this server, false if the failure has been detected while trying to send a
-    *        callback from this server to the client.
-    */
-   void handleClientFailure(String remotingSessionID, boolean clientToServer);
+   void handleClientFailure(String remotingSessionID);
    
    void registerConnectionFactory(ServerConnectionFactoryEndpoint cf);
    

Modified: branches/Branch_JBossMessaging_1_4_0_SP3_CP/src/main/org/jboss/jms/server/connectionmanager/SimpleConnectionManager.java
===================================================================
--- branches/Branch_JBossMessaging_1_4_0_SP3_CP/src/main/org/jboss/jms/server/connectionmanager/SimpleConnectionManager.java	2008-03-27 14:19:11 UTC (rev 3963)
+++ branches/Branch_JBossMessaging_1_4_0_SP3_CP/src/main/org/jboss/jms/server/connectionmanager/SimpleConnectionManager.java	2008-03-27 17:51:04 UTC (rev 3964)
@@ -95,7 +95,7 @@
 
    // ConnectionManager implementation -------------------------------------------------------------
    
-   
+ 
    public synchronized void registerConnection(String jmsClientVMID,
                                                String remotingClientSessionID,
                                                ConnectionEndpoint endpoint)
@@ -175,7 +175,7 @@
       
       if (handlers != null)
       {
-      	ServerInvokerCallbackHandler handler = handlers.remove(remotingSessionID);
+      	handlers.remove(remotingSessionID);
       	
       	if (handlers.isEmpty())
       	{
@@ -194,27 +194,11 @@
       return list;
    }
       
-   public synchronized void handleClientFailure(String remotingSessionID, boolean clientToServer)
+   public synchronized void handleClientFailure(String remotingSessionID)
    {
-      String jmsClientID = (String)remotingSessions.get(remotingSessionID);
-
-      if (jmsClientID == null)
-      {
-         log.warn(this + " cannot look up remoting session ID " + remotingSessionID);
-      }
-
-      log.warn("A problem has been detected " +
-         (clientToServer ?
-            "with the connection to remote client ":
-            "trying to send a message to remote client ") +
-         remotingSessionID + ", jmsClientID=" + jmsClientID + ". It is possible the client has exited without closing " +
-         "its connection(s) or the network has failed. All connection resources " +
-         "corresponding to that client process will now be removed.");
-
-      closeConsumersForClientVMID(jmsClientID);
+      cleanupForSessionID(remotingSessionID);
    }
    
-
    public void registerConnectionFactory(ServerConnectionFactoryEndpoint cf)
    {
    	connectionFactories.add(cf);
@@ -249,15 +233,12 @@
       
       if (remotingSessionID != null)
       {
-         handleClientFailure(remotingSessionID, true);
+         handleClientFailure(remotingSessionID);
       }
    }
-   
-  
-
+     
    // ClusterNotificationListener implementation ---------------------------------------------------
 
-
    /**
     * Closing connections that are coming from a failed node
     * @param notification
@@ -301,7 +282,10 @@
 
             log.trace("Closing consumers for clientVMID=" + clientVMID);
 
-            closeConsumersForClientVMID(clientVMID);
+            if (clientVMID != null)
+            {
+            	cleanupForVMID(clientVMID);
+            }
 			}
 			catch (Exception e)
 			{
@@ -357,84 +341,180 @@
 
    // Private --------------------------------------------------------------------------------------
   
-   private synchronized void closeConsumersForClientVMID(String jmsClientID)
+   private synchronized void cleanupForVMID(String jmsClientID)
    {
-      if (jmsClientID == null)
-      {
-         return;
-      }
-
       Map<String, ConnectionEndpoint> endpoints = jmsClients.get(jmsClientID);
 
       if (endpoints != null)
       {
-         List<ConnectionEndpoint> sces = new ArrayList<ConnectionEndpoint>();
+      	//Copy to prevent ConcurrentModificationException
+         List<ConnectionEndpoint> sces = new ArrayList<ConnectionEndpoint>(endpoints.values());
 
-         for (Map.Entry<String, ConnectionEndpoint> entry: endpoints.entrySet())
-         {
-            ConnectionEndpoint sce = entry.getValue();
-            sces.add(sce);
-         }
-
          // Now close the end points - this will result in a callback into unregisterConnection
          // to remove the data from the jmsClients and sessions maps.
-         // Note we do this outside the loop to prevent ConcurrentModificationException
 
          for(ConnectionEndpoint sce: sces )
          {
+   			log.debug("clearing up state for connection " + sce);
+
+            // sce could also be a mock test.. so this test is required
+            if (sce instanceof ServerConnectionEndpoint)
+            {
+               //Remoting is dumb and doesn't clean up it's state after itself - so we have to do it.
+               ((ServerConnectionEndpoint)sce).closeCallbackClient();
+            }
+   			
             try
             {
-      			log.debug("clearing up state for connection " + sce);
-
-               // sce could also be a mock test.. so this test is required
-               if (sce instanceof ServerConnectionEndpoint)
-               {
-                  //Remoting is dumb and doesn't clean up it's state after itself - so we have to do it.
-                  ((ServerConnectionEndpoint)sce).closeCallbackClient();
-               }
-      			
-               sce.closing(-1);
-               sce.close();
-               log.debug("cleared up state for connection " + sce);
+            	sce.closing(-1);
             }
-            catch (JMSException e)
+            catch (Throwable ignore)
+            {               	
+            }
+            try
             {
-               log.error("Failed to close connection", e);
-            }          
+            	sce.close();
+            }
+            catch (Throwable ignore)
+            {               	
+            }
+            log.debug("cleared up state for connection " + sce);      
          }
       }
       
       Map<String, ServerInvokerCallbackHandler> handlers = cfHandlers.remove(jmsClientID);
-      
+            
       if (handlers != null)
       {      	
-         for (ServerInvokerCallbackHandler handler: handlers.values())
+      	Map<String, ServerInvokerCallbackHandler> handlersClone = new HashMap<String, ServerInvokerCallbackHandler>(handlers);
+      	      	
+         for (Map.Entry<String, ServerInvokerCallbackHandler> entry: handlersClone.entrySet())
          {
             try
             {
-               handler.getCallbackClient().disconnect();
+               entry.getValue().getCallbackClient().disconnect();
             }
-            catch (Throwable e)
+            catch (Throwable ignore)
             {
-               //Ignore
             }
 
             try
             {
-               handler.destroy();
+               entry.getValue().destroy();
             }
-            catch (Throwable e)
+            catch (Throwable ignore)
             {
-               //Ignore
             }           
             
             for (ServerConnectionFactoryEndpoint ep: connectionFactories)
             {
-            	ep.removeCallbackhandler(handler);
+            	ep.removeCallbackhandler(entry.getValue());
             }
+            
+            unregisterConnectionFactoryCallback(jmsClientID, entry.getKey());
          }
       }
+   }
+         
+   private void cleanupForSessionID(String jmsSessionID)
+   {      
+   	String jmsClientID = remotingSessions.get(jmsSessionID);
+   	
+      log.warn("A problem has been detected " +
+               "with the connection to remote client " +
+               jmsSessionID + ", jmsClientID=" + jmsClientID + ". It is possible the client has exited without closing " +
+            "its connection(s) or the network has failed. All associated connection resources will be cleaned up.");
+   	
+   	if (jmsClientID != null)
+   	{      	
+         Map<String, ConnectionEndpoint> endpoints = jmsClients.get(jmsClientID);
+   
+         if (endpoints != null)
+         {
+         	ConnectionEndpoint conn = null;
+         
+         	for (Map.Entry<String, ConnectionEndpoint> entry: endpoints.entrySet())
+         	{
+         		if (entry.getKey().equals(jmsSessionID))
+         		{   
+         			conn = entry.getValue();
+         			
+         			break;
+         		}
+         	}
+         	
+         	if (conn != null)
+         	{
+         		 // sce could also be a mock test.. so this test is required
+               if (conn instanceof ServerConnectionEndpoint)
+               {
+                  //Remoting is dumb and doesn't clean up it's state after itself - so we have to do it.
+                  ((ServerConnectionEndpoint)conn).closeCallbackClient();
+               }
+               
+               try
+               {
+               	conn.closing(-1);
+               }
+               catch (Throwable ignore)
+               {            	
+               }
+               try
+               {
+               	conn.close();
+               }
+               catch (Throwable ignore)
+               {            	
+               }
+               
+               return;
+         	}
+         }
+   	}
 
+      Map<String, ServerInvokerCallbackHandler> handlers = cfHandlers.get(jmsClientID);
+      
+      if (handlers != null)
+      {      	
+      	boolean found = false;
+      	
+      	for (Map.Entry<String, ServerInvokerCallbackHandler> entry: handlers.entrySet())
+      	{
+      		if (entry.getKey().equals(jmsSessionID))
+      		{      			      			
+               try
+               {
+                  entry.getValue().getCallbackClient().disconnect();
+               }
+               catch (Throwable ignore)
+               {
+               }
+   
+               try
+               {
+                  entry.getValue().destroy();
+               }
+               catch (Throwable ignore)
+               {
+               }           
+               
+               for (ServerConnectionFactoryEndpoint ep: connectionFactories)
+               {
+               	ep.removeCallbackhandler(entry.getValue());
+               }
+               
+               found = true;
+               
+               break;
+      		}
+         }
+      	
+      	if (found)
+      	{
+      		unregisterConnectionFactoryCallback(jmsClientID, jmsSessionID);
+      	}
+      }
+
    }
 
    // Inner classes --------------------------------------------------------------------------------

Modified: branches/Branch_JBossMessaging_1_4_0_SP3_CP/tests/src/org/jboss/test/messaging/jms/server/connectionmanager/SimpleConnectionManagerTest.java
===================================================================
--- branches/Branch_JBossMessaging_1_4_0_SP3_CP/tests/src/org/jboss/test/messaging/jms/server/connectionmanager/SimpleConnectionManagerTest.java	2008-03-27 14:19:11 UTC (rev 3963)
+++ branches/Branch_JBossMessaging_1_4_0_SP3_CP/tests/src/org/jboss/test/messaging/jms/server/connectionmanager/SimpleConnectionManagerTest.java	2008-03-27 17:51:04 UTC (rev 3964)
@@ -106,14 +106,19 @@
 	       
 	      entry = (Map.Entry)iter.next();
 	      
+	      String sessId2 = (String)entry.getKey();
+	      
 	      //Simulate failure of connection
 	      
-	      cm.handleClientFailure(sessId1, true);
+	      cm.handleClientFailure(sessId1);
+  
+	      jmsClients = cm.getClients();
+	      assertEquals(1, jmsClients.size());        
 	      
-	      //both connections should be shut
+	      cm.handleClientFailure(sessId2);
 	      
 	      jmsClients = cm.getClients();
-	      assertEquals(0, jmsClients.size());        
+	      assertEquals(0, jmsClients.size());   
       }
       finally
       {
@@ -175,23 +180,24 @@
 
       assertFalse(cm.containsRemotingSession("sessionid5"));
 
-      cm.handleClientFailure("sessionid4", true);
+      cm.handleClientFailure("sessionid4");
 
       assertNull(cm.unregisterConnection("jvm2", "sessionid4"));
-      assertNull(cm.unregisterConnection("jvm2", "sessionid3"));
+      ConnectionEndpoint r3 = cm.unregisterConnection("jvm2", "sessionid3");
+      assertEquals(e3, r3);
+      assertFalse(e3.isClosed());
 
       assertFalse(cm.containsRemotingSession("sessionid4"));
       assertFalse(cm.containsRemotingSession("sessionid3"));
 
-      assertTrue(e3.isClosed());
       assertTrue(e4.isClosed());
 
-      ConnectionEndpoint r3 = cm.unregisterConnection("jvm1", "sessionid1");
-      assertEquals(e1, r3);
+      ConnectionEndpoint r4 = cm.unregisterConnection("jvm1", "sessionid1");
+      assertEquals(e1, r4);
       assertFalse(e1.isClosed());
 
-      ConnectionEndpoint r4 = cm.unregisterConnection("jvm1", "sessionid2");
-      assertEquals(e2, r4);
+      ConnectionEndpoint r5 = cm.unregisterConnection("jvm1", "sessionid2");
+      assertEquals(e2, r5);
       assertFalse(e2.isClosed());
 
       assertFalse(cm.containsRemotingSession("sessionid2"));




More information about the jboss-cvs-commits mailing list