/// <summary> /// Gets a connection from the next host according to the load balancing policy /// </summary> /// <exception cref="NoHostAvailableException"/> /// <exception cref="InvalidQueryException">When keyspace does not exist</exception> /// <exception cref="UnsupportedProtocolVersionException"/> internal Connection GetNextConnection(IStatement statement) { var hostEnumerable = _session.Policies.LoadBalancingPolicy.NewQueryPlan(_session.Keyspace, statement); //hostEnumerable GetEnumerator will return a NEW enumerator, making this call thread safe foreach (var host in hostEnumerable) { if (!host.IsConsiderablyUp) { continue; } Host = host; _triedHosts[host.Address] = null; Connection connection = null; try { var distance = _session.Policies.LoadBalancingPolicy.Distance(host); var hostPool = _session.GetConnectionPool(host, distance); connection = hostPool.BorrowConnection(); if (connection == null) { continue; } connection.Keyspace = _session.Keyspace; return(connection); } catch (SocketException ex) { SetHostDown(host, connection, ex); _triedHosts[host.Address] = ex; } catch (InvalidQueryException) { //The keyspace does not exist throw; } catch (UnsupportedProtocolVersionException) { //The version of the protocol is not supported throw; } catch (Exception ex) { _logger.Error(ex); _triedHosts[host.Address] = ex; } } Host = null; throw new NoHostAvailableException(_triedHosts); }
/// <summary> /// Gets a connection from the next host according to the load balancing policy /// </summary> /// <exception cref="NoHostAvailableException"/> /// <exception cref="InvalidQueryException">When keyspace does not exist</exception> /// <exception cref="UnsupportedProtocolVersionException"/> internal Connection GetNextConnection(IStatement statement, bool isLastChance = false) { var hostEnumerable = _session.Policies.LoadBalancingPolicy.NewQueryPlan(statement); Host lastChanceHost = null; //hostEnumerable GetEnumerator will return a NEW enumerator, making this call thread safe foreach (var host in hostEnumerable) { if (!host.IsConsiderablyUp) { if (!isLastChance && host.Resurrect) { lastChanceHost = host; } continue; } _currentHost = host; _triedHosts[host.Address] = null; Connection connection = null; try { var distance = _session.Policies.LoadBalancingPolicy.Distance(host); var hostPool = _session.GetConnectionPool(host, distance); connection = hostPool.BorrowConnection(); if (connection == null) { continue; } connection.Keyspace = _session.Keyspace; return(connection); } catch (SocketException ex) { _session.SetHostDown(host, connection); _triedHosts[host.Address] = ex; host.Resurrect = CanBeResurrected(ex, connection); if (!isLastChance && host.Resurrect) { lastChanceHost = host; } } catch (InvalidQueryException) { //The keyspace does not exist throw; } catch (UnsupportedProtocolVersionException) { //The version of the protocol is not supported throw; } catch (Exception ex) { _logger.Error(ex); _triedHosts[host.Address] = ex; } } _currentHost = null; if (lastChanceHost != null) { //There are no host available and some of them are due to network events. //Probably there was a network event that reset all connections and it does not mean the connection _logger.Warning("Suspected network reset. Getting one host up and retrying for a last chance"); lastChanceHost.BringUpIfDown(); return(GetNextConnection(statement, true)); } throw new NoHostAvailableException(_triedHosts); }