private Task<bool> IterateAndConnect(IEnumerator<Host> hostsEnumerator, Dictionary<IPEndPoint, Exception> triedHosts) { var available = hostsEnumerator.MoveNext(); if (!available) { return TaskHelper.FromException<bool>(new NoHostAvailableException(triedHosts)); } var host = hostsEnumerator.Current; var c = new Connection(_serializer, host.Address, _config); return ((Task) c .Open()) .ContinueWith(t => { if (t.Status == TaskStatus.RanToCompletion) { _connection = c; _host = host; _logger.Info("Connection established to {0}", c.Address); return TaskHelper.ToTask(true); } if (t.IsFaulted && t.Exception != null) { var ex = t.Exception.InnerException; if (ex is UnsupportedProtocolVersionException) { //Use the protocol version used to parse the response message var nextVersion = _serializer.ProtocolVersion; _logger.Info(string.Format("{0}, trying with version {1}", ex.Message, nextVersion)); c.Dispose(); if (ProtocolVersion < 1) { throw new DriverInternalError("Invalid protocol version"); } //Retry using the new protocol version return Connect(true); } //There was a socket exception or an authentication exception triedHosts.Add(host.Address, ex); c.Dispose(); return IterateAndConnect(hostsEnumerator, triedHosts); } throw new TaskCanceledException("The ControlConnection could not be connected."); }, TaskContinuationOptions.ExecuteSynchronously) .Unwrap(); }
/// <exception cref="System.Net.Sockets.SocketException">Throws a SocketException when the connection could not be established with the host</exception> /// <exception cref="AuthenticationException" /> /// <exception cref="UnsupportedProtocolVersionException"></exception> internal virtual Task<Connection> CreateConnection() { Logger.Info("Creating a new connection to the host " + _host.Address); var c = new Connection(_serializer, _host.Address, _config); return c.Open().ContinueWith(t => { if (t.Status == TaskStatus.RanToCompletion) { if (_config.GetPoolingOptions(_serializer.ProtocolVersion).GetHeartBeatInterval() > 0) { //Heartbeat is enabled, subscribe for possible exceptions c.OnIdleRequestException += OnIdleRequestException; } return c; } Logger.Info("The connection to {0} could not be opened", _host.Address); c.Dispose(); if (t.Exception != null) { t.Exception.Handle(_ => true); Logger.Error(t.Exception.InnerException); throw t.Exception.InnerException; } throw new TaskCanceledException("The connection creation task was cancelled"); }, TaskContinuationOptions.ExecuteSynchronously); }