/// <summary> /// Tries to fail-over the connection, if the connection policy will permit it, and the fail-over process has not yet been /// started. If the connection does not allow fail-over then an exception will be raised. If a fail-over is already in progress /// this method allows it to continue to run and will do nothing. /// /// <p/>This method should only be called when the connection has been remotely closed. /// </summary> /// /// <returns>The fail-over state at the end of this attempt.</returns> private FailoverState AttemptFailover() { _log.Debug("private void AttemptFailover(): called"); _log.Debug("_failoverState = " + _failoverState); // Ensure that the connection stops sending heart beats, if it still is. _connection.StopHeartBeatThread(); // Check that the connection policy allows fail-over to be attempted. if (!_connection.IsFailoverAllowed) { _log.Debug("Connection does not allowed to failover"); _connection.ExceptionReceived( new AMQDisconnectedException("Broker closed connection and reconnection is not permitted.")); } // Check if connection was closed deliberately by the application, in which case no fail-over is attempted. if (_connection.Closed) { return(_failoverState); } // If the connection allows fail-over and fail-over has not yet been started, then it is started and the fail-over state is // advanced to 'in progress' if (_failoverState == FailoverState.NOT_STARTED && _connection.IsFailoverAllowed) { _log.Info("Starting the fail-over process."); _failoverState = FailoverState.IN_PROGRESS; StartFailoverThread(); } return(_failoverState); }
/// <summary> /// Receives notification of any IO exceptions on the connection. /// /// <p/>Upon receipt of a connection closed exception or any IOException, the fail-over process is attempted. If the fail-over fails, then /// all method listeners and the application connection object are notified of the connection failure exception. /// /// <p/>All other exception types are propagated to all method listeners. /// </summary> public void OnException(Exception cause) { _log.Warn("public void OnException(Exception cause = " + cause + "): called"); // Ensure that the method listener set cannot be changed whilst this exception is propagated to all listeners. This also // ensures that this exception is fully propagated to all listeners, before another one can be processed. lock (_lock) { if (cause is AMQConnectionClosedException || cause is System.IO.IOException) { // Try a fail-over because the connection has failed. FailoverState failoverState = AttemptFailover(); // Check if the fail-over has failed, in which case notify all method listeners of the exception. // The application connection object is also notified of the failure of the connection with the exception. if (failoverState == FailoverState.FAILED) { _log.Debug("Fail-over has failed. Notifying all method listeners of the exception."); AMQException amqe = new AMQException("Protocol handler error: " + cause, cause); PropagateExceptionToWaiters(amqe); _connection.ExceptionReceived(cause); } } // Notify all method listeners of the exception. else { PropagateExceptionToWaiters(cause); _connection.ExceptionReceived(cause); } } }
/// <summary> /// Tries to fail-over the connection, if the connection policy will permit it, and the fail-over process has not yet been /// started. If the connection does not allow fail-over then an exception will be raised. If a fail-over is already in progress /// this method allows it to continue to run and will do nothing. /// /// <p/>This method should only be called when the connection has been remotely closed. /// </summary> /// /// <returns>The fail-over state at the end of this attempt.</returns> private FailoverState AttemptFailover() { _log.Debug("private void AttemptFailover(): called"); _log.Debug("_failoverState = " + _failoverState); // Ensure that the connection stops sending heart beats, if it still is. _connection.StopHeartBeatThread(); // Check that the connection policy allows fail-over to be attempted. if (!_connection.IsFailoverAllowed) { _log.Debug("Connection does not allowed to failover"); _connection.ExceptionReceived( new AMQDisconnectedException("Broker closed connection and reconnection is not permitted.")); } // Check if connection was closed deliberately by the application, in which case no fail-over is attempted. if (_connection.Closed) { return _failoverState; } // If the connection allows fail-over and fail-over has not yet been started, then it is started and the fail-over state is // advanced to 'in progress' if (_failoverState == FailoverState.NOT_STARTED && _connection.IsFailoverAllowed) { _log.Info("Starting the fail-over process."); _failoverState = FailoverState.IN_PROGRESS; StartFailoverThread(); } return _failoverState; }