private void HandleConnectionException(Exception ex) { var oldFactory = ConnectionFactory; var nextFactory = _connectionFactories.GetNext(); if (++_nodeTried < _connectionFactories.All.Count()) { _watcher.ErrorFormat("Failed to connect to Broker: '{0}:{1}', VHost: '{2}'. Failing over to '{3}:{4}'\nExceptionMessage: {5}", oldFactory.HostName, oldFactory.Port, oldFactory.VirtualHost, nextFactory.HostName, nextFactory.Port, ex.Message); Connect(); } else { _watcher.ErrorFormat("Failed to connect to Broker: '{0}:{1}', VHost: '{2}'. Failing over to '{3}{4}' after {5}ms\nExceptionMessage: {6}", oldFactory.HostName, oldFactory.Port, oldFactory.VirtualHost, nextFactory.HostName, nextFactory.Port, _retryPolicy.DelayTime, ex.Message); _retryPolicy.WaitForNextRetry(Connect); } }
/// <summary> /// Initialize a <see cref="HaConnection"/> with a list of <see cref="ManagedConnectionFactory"/> /// These connection factories are responsibile for creating <see cref="IConnection"/> to nodes in the clusters /// </summary> /// <param name="retryPolicy"></param> /// <param name="watcher"></param> /// <param name="connectionFactories"></param> public HaConnection(IRetryPolicy retryPolicy, IRabbitWatcher watcher, IList <ManagedConnectionFactory> connectionFactories) : base(retryPolicy, watcher) { _connectionFactories = new RoundRobinList <ConnectionFactory>(connectionFactories); ConnectionEstablished handler = (endpoint, virtualHost) => { if (_connectionFactories.All.Any(f => f.Endpoint + f.VirtualHost == endpoint + virtualHost)) { if (!IsConnected) { while (_connectionFactories.Current.Endpoint + _connectionFactories.Current.VirtualHost != endpoint + virtualHost) { //IF there are 2 different Tunnels using 2 HaConnection with 2 lists of cluster nodes in different orders: //Example: // ConnectionString1: host=q1;username=guest;password=guest|host=q2;username=guest;password=guest|host=q3;username=guest;password=guest // ConnectionString2: host=q2;username=guest;password=guest|host=q3;username=guest;password=guest|host=q1;username=guest;password=guest // When the first tunnel established the connection successfully to q1, it fires event and these lines of code is triggered. // The 2nd HaConnection needs to set it's _connectionFactories.Current to q1 established by other tunnel. Before changing, _connectionFactories.Current is q3 by the order in the ConnectionString2 _connectionFactories.GetNext(); } } FireConnectedEvent(); } }; ManagedConnectionFactory.ConnectionEstablished += handler; _unsubscribeEvents = () => { ManagedConnectionFactory.ConnectionEstablished -= handler; }; }