[jboss-cvs] JBoss Messaging SVN: r6801 - tags/JBossMessaging_1_4_0_SP3_CP03_1456/src/main/org/jboss/jms/client.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri May 15 00:58:23 EDT 2009
Author: gaohoward
Date: 2009-05-15 00:58:23 -0400 (Fri, 15 May 2009)
New Revision: 6801
Modified:
tags/JBossMessaging_1_4_0_SP3_CP03_1456/src/main/org/jboss/jms/client/FailoverCommandCenter.java
Log:
avoid null point in log
Modified: tags/JBossMessaging_1_4_0_SP3_CP03_1456/src/main/org/jboss/jms/client/FailoverCommandCenter.java
===================================================================
--- tags/JBossMessaging_1_4_0_SP3_CP03_1456/src/main/org/jboss/jms/client/FailoverCommandCenter.java 2009-05-15 02:12:06 UTC (rev 6800)
+++ tags/JBossMessaging_1_4_0_SP3_CP03_1456/src/main/org/jboss/jms/client/FailoverCommandCenter.java 2009-05-15 04:58:23 UTC (rev 6801)
@@ -1,313 +1,316 @@
-/**
- * JBoss, Home of Professional Open Source
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.jms.client;
-
-import org.jboss.jms.client.delegate.ClientConnectionDelegate;
-import org.jboss.jms.client.remoting.JMSRemotingConnection;
-import org.jboss.jms.client.state.ConnectionState;
-import org.jboss.jms.debug.ClientFailoverTracker;
-import org.jboss.jms.debug.JMSObjectTracker;
-import org.jboss.jms.debug.TrackerFactory;
-import org.jboss.jms.delegate.ConnectionFactoryDelegate;
-import org.jboss.jms.delegate.CreateConnectionResult;
-import org.jboss.logging.Logger;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * The class in charge with performing the failover.
- *
- * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class FailoverCommandCenter
-{
- // Constants ------------------------------------------------------------------------------------
-
- private static final Logger log = Logger.getLogger(FailoverCommandCenter.class);
-
- // Static ---------------------------------------------------------------------------------------
-
- private static boolean trace = log.isTraceEnabled();
-
- // Attributes-----------------------------------------------------------------------------------
-
- private ConnectionState state;
-
- private FailoverValve2 valve;
-
- private List failoverListeners;
-
- // Constructors ---------------------------------------------------------------------------------
-
- public FailoverCommandCenter(ConnectionState state)
- {
- this.state = state;
- failoverListeners = new ArrayList();
-
- valve = new FailoverValve2();
- }
-
- // Public ---------------------------------------------------------------------------------------
-
- public void setState(ConnectionState state)
- {
- this.state = state;
- }
-
- /**
- * Method called by failure detection components (FailoverValveInterceptors and
- * ConnectionListeners) when they have reasons to believe that a server failure occured.
- *
- * Returns true if the failover command centre handled the exception gracefully and failover completed
- * or false if it didn't and failover did not occur
- */
- public boolean failureDetected(Throwable reason, FailureDetector source,
- JMSRemotingConnection remotingConnection)
- throws Exception
- {
-
- ClientFailoverTracker tracker = TrackerFactory.getClientFailoverTracker();
- log.debug("failure detected by " + source, reason);
-
- tracker.report("failure detected by " + source + " rmoting " + remotingConnection +
- " client: " + remotingConnection.getRemotingClient().getSessionId(), reason, true);
- tracker.report("connection, client id: " + state.getClientID() + " server id: " +
- state.getServerID() + "conn id: " + state.getDelegate().getID() +
- " conn remoting " + ((ClientConnectionDelegate)state.getDelegate()).getRemotingConnection(), null, false);
- // generate a FAILURE_DETECTED event
- broadcastFailoverEvent(new FailoverEvent(FailoverEvent.FAILURE_DETECTED, source));
-
- CreateConnectionResult res = null;
-
- boolean failoverSuccessful = false;
-
- boolean valveOpened = false;
-
- int failoverEvent = FailoverEvent.FAILOVER_COMPLETED;
-
- try
- {
- // block any other invocations ariving to any delegate from the hierarchy while we're
- // doing failover
-
- valve.close();
-
- synchronized(this)
- {
- // testing for failed connection and setting the failed flag need to be done in one
- // atomic operation, otherwise multiple threads can get to perform the client-side
- // failover concurrently
- if (remotingConnection.isFailed())
- {
- log.debug(this + " ignoring failure detection notification, as failover was " +
- "already (or is in process of being) performed on this connection");
-
- failoverSuccessful = true;
-
- failoverEvent = FailoverEvent.FAILOVER_ALREADY_COMPLETED;
-
- tracker.report("somebody already done failover", null, false);
- //Return true since failover already completed ok
- return true;
- }
-
- tracker.report("setting remoting connection failed. remoting session id: " +
- remotingConnection.getRemotingClient().getSessionId(), null, false);
- remotingConnection.setFailed();
- tracker.report("done set failed.", null, false);
- }
-
- // Note - failover doesn't occur until _after_ the above check - so the next comment
- // belongs here
- log.info("JBoss Messaging server failure detected - waiting for failover to complete...");
-
- // generate a FAILOVER_STARTED event. The event must be broadcasted AFTER valve closure,
- // to insure the client-side stack is in a deterministic state
- broadcastFailoverEvent(new FailoverEvent(FailoverEvent.FAILOVER_STARTED, this));
-
- int failedNodeID = state.getServerID();
-
- ConnectionFactoryDelegate clusteredDelegate = state.getClusteredConnectionFactoryDelegate();
-
- // try recreating the connection
- log.trace("Creating new connection");
- res = clusteredDelegate.
- createConnectionDelegate(state.getUsername(), state.getPassword(), failedNodeID);
- log.trace("Created connection");
-
- if (res == null)
- {
- // Failover did not occur
- failoverSuccessful = false;
- log.trace("No failover");
- }
- else
- {
- // recursively synchronize state
- ClientConnectionDelegate newDelegate = (ClientConnectionDelegate)res.getDelegate();
-
- tracker.report("new conn Delegate got: " + newDelegate.getID() + " clientID: (cannot call it)" +
- " server ID: " + newDelegate.getServerID(), null, false);
-
- log.trace("Synchronizing state");
- state.getDelegate().synchronizeWith(newDelegate);
- log.trace("Synchronized state");
-
- tracker.report("state synchronized", null, false);
-
- //Now restart the connection if appropriate
- //Note! we mus start the connection while the valve is still closed
- //Otherwise If a consumer closing is waiting on failover to complete
- //Then on failover complete the valve will be opened and closing retried on a
- //different thread
- //but the next line will re-start the connection so there is a race between the two
- //If the restart hits after closing then messages can get delivered after consumer
- //is closed
-
- if (state.isStarted())
- {
- log.trace("Starting new connection");
- tracker.report("restart the new connection" , null, false);
- newDelegate.startAfterFailover();
- tracker.report("restarted" , null, false);
- log.trace("Started new connection");
- }
-
- if(remotingConnection.getConnectionListener() != null &&
- remotingConnection.getConnectionListener().getJMSExceptionListener() != null)
- {
- log.trace("Adding Exception Listener to new connection");
- tracker.report("setting exception listener on new delegate: " + newDelegate.getID(), null, false);
- newDelegate.setExceptionListener(remotingConnection.getConnectionListener().getJMSExceptionListener());
- }
- log.trace("Opening valve");
- valve.open();
- tracker.report("valve opened", null, false);
- log.trace("Opened valve");
- valveOpened = true;
-
- failoverSuccessful = true;
-
- log.info("JBoss Messaging failover complete");
- }
-
- log.trace("failureDetected() complete");
-
- tracker.report("failover end with: " + failoverSuccessful, null, false);
- return failoverSuccessful;
- }
- catch (Exception e)
- {
- log.error("Failover failed", e);
-
- tracker.report("failover failed." , e, false);
- throw e;
- }
- finally
- {
- if (!valveOpened)
- {
- log.trace("finally opening valve");
- valve.open();
- tracker.report("finally valve opened.", null, false);
- log.trace("valve opened");
- }
-
- if (failoverSuccessful)
- {
- log.debug(this + " completed successful failover");
- broadcastFailoverEvent(new FailoverEvent(failoverEvent, this));
- tracker.report("finally failover ok", null, false);
- }
- else
- {
- log.debug(this + " aborted failover");
- tracker.report("finally abort failover", null, false);
- ClientConnectionDelegate connDelegate = (ClientConnectionDelegate)state.getDelegate();
- connDelegate.closing(-1);
- connDelegate.close();
- tracker.report("aborted conn: " + connDelegate.getID(), null, false);
- broadcastFailoverEvent(new FailoverEvent(FailoverEvent.FAILOVER_FAILED, this));
- }
- }
- }
-
- public void registerFailoverListener(FailoverListener listener)
- {
- synchronized(failoverListeners)
- {
- failoverListeners.add(listener);
- }
- }
-
- public boolean unregisterFailoverListener(FailoverListener listener)
- {
- synchronized(failoverListeners)
- {
- return failoverListeners.remove(listener);
- }
- }
-
- public FailoverValve2 getValve()
- {
- return valve;
- }
-
- public JMSRemotingConnection getRemotingConnection()
- {
- return state.getRemotingConnection();
- }
-
- public String toString()
- {
- return "FailoverCommandCenter[" + state + "]";
- }
-
- // Package protected ----------------------------------------------------------------------------
-
- ConnectionState getConnectionState()
- {
- return state;
- }
-
- // Protected ------------------------------------------------------------------------------------
-
- // Private --------------------------------------------------------------------------------------
-
- private void broadcastFailoverEvent(FailoverEvent e)
- {
- if (trace) { log.trace(this + " broadcasting " + e); }
-
- List listenersCopy;
-
- synchronized(failoverListeners)
- {
- listenersCopy = new ArrayList(failoverListeners);
- }
-
- for(Iterator i = listenersCopy.iterator(); i.hasNext(); )
- {
- FailoverListener listener = (FailoverListener)i.next();
-
- try
- {
- listener.failoverEventOccured(e);
- }
- catch(Exception ex)
- {
- log.warn("Failover listener " + listener + " did not accept event", ex);
- }
- }
- }
-
- // Inner classes --------------------------------------------------------------------------------
-}
+/**
+ * JBoss, Home of Professional Open Source
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jboss.jms.client;
+
+import org.jboss.jms.client.delegate.ClientConnectionDelegate;
+import org.jboss.jms.client.remoting.JMSRemotingConnection;
+import org.jboss.jms.client.state.ConnectionState;
+import org.jboss.jms.debug.ClientFailoverTracker;
+import org.jboss.jms.debug.JMSObjectTracker;
+import org.jboss.jms.debug.TrackerFactory;
+import org.jboss.jms.delegate.ConnectionFactoryDelegate;
+import org.jboss.jms.delegate.CreateConnectionResult;
+import org.jboss.logging.Logger;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * The class in charge with performing the failover.
+ *
+ * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ */
+public class FailoverCommandCenter
+{
+ // Constants ------------------------------------------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(FailoverCommandCenter.class);
+
+ // Static ---------------------------------------------------------------------------------------
+
+ private static boolean trace = log.isTraceEnabled();
+
+ // Attributes-----------------------------------------------------------------------------------
+
+ private ConnectionState state;
+
+ private FailoverValve2 valve;
+
+ private List failoverListeners;
+
+ // Constructors ---------------------------------------------------------------------------------
+
+ public FailoverCommandCenter(ConnectionState state)
+ {
+ this.state = state;
+ failoverListeners = new ArrayList();
+
+ valve = new FailoverValve2();
+ }
+
+ // Public ---------------------------------------------------------------------------------------
+
+ public void setState(ConnectionState state)
+ {
+ this.state = state;
+ }
+
+ /**
+ * Method called by failure detection components (FailoverValveInterceptors and
+ * ConnectionListeners) when they have reasons to believe that a server failure occured.
+ *
+ * Returns true if the failover command centre handled the exception gracefully and failover completed
+ * or false if it didn't and failover did not occur
+ */
+ public boolean failureDetected(Throwable reason, FailureDetector source,
+ JMSRemotingConnection remotingConnection)
+ throws Exception
+ {
+
+ ClientFailoverTracker tracker = TrackerFactory.getClientFailoverTracker();
+ log.debug("failure detected by " + source, reason);
+
+ Client theClient = remotingConnection.getRemotingClient();
+ String remotingSessionId = theClient == null ? "null" : theClient.getSessionId();
+
+ tracker.report("failure detected by " + source + " rmoting " + remotingConnection +
+ " client: " + remotingSessionId, reason, true);
+ tracker.report("connection, client id: " + state.getClientID() + " server id: " +
+ state.getServerID() + "conn id: " + state.getDelegate().getID() +
+ " conn remoting " + ((ClientConnectionDelegate)state.getDelegate()).getRemotingConnection(), null, false);
+ // generate a FAILURE_DETECTED event
+ broadcastFailoverEvent(new FailoverEvent(FailoverEvent.FAILURE_DETECTED, source));
+
+ CreateConnectionResult res = null;
+
+ boolean failoverSuccessful = false;
+
+ boolean valveOpened = false;
+
+ int failoverEvent = FailoverEvent.FAILOVER_COMPLETED;
+
+ try
+ {
+ // block any other invocations ariving to any delegate from the hierarchy while we're
+ // doing failover
+
+ valve.close();
+
+ synchronized(this)
+ {
+ // testing for failed connection and setting the failed flag need to be done in one
+ // atomic operation, otherwise multiple threads can get to perform the client-side
+ // failover concurrently
+ if (remotingConnection.isFailed())
+ {
+ log.debug(this + " ignoring failure detection notification, as failover was " +
+ "already (or is in process of being) performed on this connection");
+
+ failoverSuccessful = true;
+
+ failoverEvent = FailoverEvent.FAILOVER_ALREADY_COMPLETED;
+
+ tracker.report("somebody already done failover", null, false);
+ //Return true since failover already completed ok
+ return true;
+ }
+
+ tracker.report("setting remoting connection failed. remoting session id: " +
+ remotingSessionId, null, false);
+ remotingConnection.setFailed();
+ tracker.report("done set failed.", null, false);
+ }
+
+ // Note - failover doesn't occur until _after_ the above check - so the next comment
+ // belongs here
+ log.info("JBoss Messaging server failure detected - waiting for failover to complete...");
+
+ // generate a FAILOVER_STARTED event. The event must be broadcasted AFTER valve closure,
+ // to insure the client-side stack is in a deterministic state
+ broadcastFailoverEvent(new FailoverEvent(FailoverEvent.FAILOVER_STARTED, this));
+
+ int failedNodeID = state.getServerID();
+
+ ConnectionFactoryDelegate clusteredDelegate = state.getClusteredConnectionFactoryDelegate();
+
+ // try recreating the connection
+ log.trace("Creating new connection");
+ res = clusteredDelegate.
+ createConnectionDelegate(state.getUsername(), state.getPassword(), failedNodeID);
+ log.trace("Created connection");
+
+ if (res == null)
+ {
+ // Failover did not occur
+ failoverSuccessful = false;
+ log.trace("No failover");
+ }
+ else
+ {
+ // recursively synchronize state
+ ClientConnectionDelegate newDelegate = (ClientConnectionDelegate)res.getDelegate();
+
+ tracker.report("new conn Delegate got: " + newDelegate.getID() + " clientID: (cannot call it)" +
+ " server ID: " + newDelegate.getServerID(), null, false);
+
+ log.trace("Synchronizing state");
+ state.getDelegate().synchronizeWith(newDelegate);
+ log.trace("Synchronized state");
+
+ tracker.report("state synchronized", null, false);
+
+ //Now restart the connection if appropriate
+ //Note! we mus start the connection while the valve is still closed
+ //Otherwise If a consumer closing is waiting on failover to complete
+ //Then on failover complete the valve will be opened and closing retried on a
+ //different thread
+ //but the next line will re-start the connection so there is a race between the two
+ //If the restart hits after closing then messages can get delivered after consumer
+ //is closed
+
+ if (state.isStarted())
+ {
+ log.trace("Starting new connection");
+ tracker.report("restart the new connection" , null, false);
+ newDelegate.startAfterFailover();
+ tracker.report("restarted" , null, false);
+ log.trace("Started new connection");
+ }
+
+ if(remotingConnection.getConnectionListener() != null &&
+ remotingConnection.getConnectionListener().getJMSExceptionListener() != null)
+ {
+ log.trace("Adding Exception Listener to new connection");
+ tracker.report("setting exception listener on new delegate: " + newDelegate.getID(), null, false);
+ newDelegate.setExceptionListener(remotingConnection.getConnectionListener().getJMSExceptionListener());
+ }
+ log.trace("Opening valve");
+ valve.open();
+ tracker.report("valve opened", null, false);
+ log.trace("Opened valve");
+ valveOpened = true;
+
+ failoverSuccessful = true;
+
+ log.info("JBoss Messaging failover complete");
+ }
+
+ log.trace("failureDetected() complete");
+
+ tracker.report("failover end with: " + failoverSuccessful, null, false);
+ return failoverSuccessful;
+ }
+ catch (Exception e)
+ {
+ log.error("Failover failed", e);
+
+ tracker.report("failover failed." , e, false);
+ throw e;
+ }
+ finally
+ {
+ if (!valveOpened)
+ {
+ log.trace("finally opening valve");
+ valve.open();
+ tracker.report("finally valve opened.", null, false);
+ log.trace("valve opened");
+ }
+
+ if (failoverSuccessful)
+ {
+ log.debug(this + " completed successful failover");
+ broadcastFailoverEvent(new FailoverEvent(failoverEvent, this));
+ tracker.report("finally failover ok", null, false);
+ }
+ else
+ {
+ log.debug(this + " aborted failover");
+ tracker.report("finally abort failover", null, false);
+ ClientConnectionDelegate connDelegate = (ClientConnectionDelegate)state.getDelegate();
+ connDelegate.closing(-1);
+ connDelegate.close();
+ tracker.report("aborted conn: " + connDelegate.getID(), null, false);
+ broadcastFailoverEvent(new FailoverEvent(FailoverEvent.FAILOVER_FAILED, this));
+ }
+ }
+ }
+
+ public void registerFailoverListener(FailoverListener listener)
+ {
+ synchronized(failoverListeners)
+ {
+ failoverListeners.add(listener);
+ }
+ }
+
+ public boolean unregisterFailoverListener(FailoverListener listener)
+ {
+ synchronized(failoverListeners)
+ {
+ return failoverListeners.remove(listener);
+ }
+ }
+
+ public FailoverValve2 getValve()
+ {
+ return valve;
+ }
+
+ public JMSRemotingConnection getRemotingConnection()
+ {
+ return state.getRemotingConnection();
+ }
+
+ public String toString()
+ {
+ return "FailoverCommandCenter[" + state + "]";
+ }
+
+ // Package protected ----------------------------------------------------------------------------
+
+ ConnectionState getConnectionState()
+ {
+ return state;
+ }
+
+ // Protected ------------------------------------------------------------------------------------
+
+ // Private --------------------------------------------------------------------------------------
+
+ private void broadcastFailoverEvent(FailoverEvent e)
+ {
+ if (trace) { log.trace(this + " broadcasting " + e); }
+
+ List listenersCopy;
+
+ synchronized(failoverListeners)
+ {
+ listenersCopy = new ArrayList(failoverListeners);
+ }
+
+ for(Iterator i = listenersCopy.iterator(); i.hasNext(); )
+ {
+ FailoverListener listener = (FailoverListener)i.next();
+
+ try
+ {
+ listener.failoverEventOccured(e);
+ }
+ catch(Exception ex)
+ {
+ log.warn("Failover listener " + listener + " did not accept event", ex);
+ }
+ }
+ }
+
+ // Inner classes --------------------------------------------------------------------------------
+}
More information about the jboss-cvs-commits
mailing list