CassandraConnection AllocateConnection(IPAddress endPoint, out Exception outExc) { CassandraConnection nconn = null; outExc = null; try { nconn = new CassandraConnection(this, endPoint, _protocolOptions, _socketOptions, _clientOptions, _authProvider); var streamId = nconn.AllocateStreamId(); var options = ProcessExecuteOptions(nconn.ExecuteOptions(streamId)); if (!string.IsNullOrEmpty(_keyspace)) { nconn.SetKeyspace(_keyspace); } } catch (Exception ex) { if (nconn != null) { nconn.Dispose(); } if (CassandraConnection.IsStreamRelatedException(ex)) { HostIsDown(endPoint); outExc = ex; return(null); } else { throw ex; } } _logger.Info("Allocated new connection"); return(nconn); }
internal CassandraConnection Connect(Query query, IEnumerator <Host> hostsIter, List <IPAddress> triedHosts, Dictionary <IPAddress, List <Exception> > innerExceptions, out int streamId) { CheckDisposed(); lock (_connectionPool) { List <CassandraConnection> toDel = null; foreach (var conn in _trashcan) { if (conn.IsEmpty()) { _logger.Info("Connection trashed"); conn.Dispose(); if (toDel == null) { toDel = new List <CassandraConnection>(); } toDel.Add(conn); } } if (toDel != null) { foreach (var d in toDel) { _trashcan.Remove(d); } } while (true) { var currentHost = hostsIter.Current; if (currentHost == null) { var ex = new NoHostAvailableException(innerExceptions); _logger.Error("All hosts are not responding.", ex); throw ex; } if (currentHost.IsConsiderablyUp) { triedHosts.Add(currentHost.Address); var hostDistance = _policies.LoadBalancingPolicy.Distance(currentHost); if (!_connectionPool.ContainsKey(currentHost.Address)) { _connectionPool.Add(currentHost.Address, new List <CassandraConnection>()); } var pool = _connectionPool[currentHost.Address]; var poolCpy = new List <CassandraConnection>(pool); CassandraCounters.SetConnectionsCount(currentHost.Address, poolCpy.Count); CassandraConnection toReturn = null; foreach (var conn in poolCpy) { if (!conn.IsHealthy) { pool.Remove(conn); conn.Dispose(); } else { if (toReturn == null) { if (!conn.IsBusy(_poolingOptions.GetMaxSimultaneousRequestsPerConnectionTreshold(hostDistance))) { toReturn = conn; } } else { if (pool.Count > _poolingOptions.GetCoreConnectionsPerHost(hostDistance)) { if (conn.IsFree(_poolingOptions.GetMinSimultaneousRequestsPerConnectionTreshold(hostDistance))) { _trashcan.Add(conn); pool.Remove(conn); } } } } } if (toReturn != null) { streamId = toReturn.AllocateStreamId(); return(toReturn); } if (pool.Count < _poolingOptions.GetMaxConnectionPerHost(hostDistance) - 1) { bool error = false; CassandraConnection conn = null; do { Exception outExc; conn = AllocateConnection(currentHost.Address, out outExc); if (conn != null) { if (_cluster.Metadata != null) { _cluster.Metadata.BringUpHost(currentHost.Address, this); } pool.Add(conn); } else { if (!innerExceptions.ContainsKey(currentHost.Address)) { innerExceptions.Add(currentHost.Address, new List <Exception>()); } innerExceptions[currentHost.Address].Add(outExc); _logger.Info("New connection attempt failed - goto another host."); error = true; break; } }while (pool.Count < _poolingOptions.GetCoreConnectionsPerHost(hostDistance)); if (!error) { streamId = conn.AllocateStreamId(); return(conn); } } } _logger.Verbose(string.Format("Currently tried host: {0} have all of connections busy. Switching to the next host.", currentHost.Address)); if (!hostsIter.MoveNext()) { var ex = new NoHostAvailableException(innerExceptions); _logger.Error("Cannot connect to any host from pool.", ex); throw ex; } } } }
CassandraConnection AllocateConnection(IPAddress endPoint, HostDistance hostDistance, out Exception outExc) { CassandraConnection nconn = null; outExc = null; try { int no = 1; if (!_allocatedConnections.TryAdd(endPoint, new AtomicValue <int>(1))) { AtomicValue <int> val; _allocatedConnections.TryGetValue(endPoint, out val); no = Interlocked.Increment(ref val.RawValue); if (no > _poolingOptions.GetMaxConnectionPerHost(hostDistance)) { Interlocked.Decrement(ref val.RawValue); outExc = new ToManyConnectionsPerHost(); return(null); } } RETRY: nconn = new CassandraConnection(this, endPoint, _protocolOptions, _socketOptions, _clientOptions, _authProvider, _authInfoProvider, _binaryProtocolVersion); var streamId = nconn.AllocateStreamId(); try { var options = ProcessExecuteOptions(nconn.ExecuteOptions(streamId)); } catch (CassandraConnectionBadProtocolVersionException) { if (_binaryProtocolVersion == 1) { throw; } else { _binaryProtocolVersion = 1; goto RETRY; } } if (!string.IsNullOrEmpty(_keyspace)) { nconn.SetKeyspace(_keyspace); } } catch (Exception ex) { if (nconn != null) { nconn.Dispose(); nconn = null; } AtomicValue <int> val; _allocatedConnections.TryGetValue(endPoint, out val); Interlocked.Decrement(ref val.RawValue); if (CassandraConnection.IsStreamRelatedException(ex)) { HostIsDown(endPoint); outExc = ex; return(null); } else { throw ex; } } _logger.Info("Allocated new connection"); return(nconn); }
CassandraConnection AllocateConnection(IPAddress endPoint, HostDistance hostDistance, out Exception outExc) { CassandraConnection nconn = null; outExc = null; try { int no = 1; if (!_allocatedConnections.TryAdd(endPoint, new AtomicValue<int>(1))) { AtomicValue<int> val; _allocatedConnections.TryGetValue(endPoint, out val); no = Interlocked.Increment(ref val.RawValue); if (no > _poolingOptions.GetMaxConnectionPerHost(hostDistance)) { Interlocked.Decrement(ref val.RawValue); outExc = new ToManyConnectionsPerHost(); return null; } } nconn = new CassandraConnection(this, endPoint, _protocolOptions, _socketOptions, _clientOptions, _authProvider); var streamId = nconn.AllocateStreamId(); var options = ProcessExecuteOptions(nconn.ExecuteOptions(streamId)); if (!string.IsNullOrEmpty(_keyspace)) nconn.SetKeyspace(_keyspace); } catch (Exception ex) { if (nconn != null) { nconn.Dispose(); nconn = null; } AtomicValue<int> val; _allocatedConnections.TryGetValue(endPoint, out val); Interlocked.Decrement(ref val.RawValue); if (CassandraConnection.IsStreamRelatedException(ex)) { HostIsDown(endPoint); outExc = ex; return null; } else throw ex; } _logger.Info("Allocated new connection"); return nconn; }
internal CassandraConnection Connect(IEnumerator <Host> hostsIter, List <IPAddress> triedHosts, Dictionary <IPAddress, List <Exception> > innerExceptions, out int streamId) { CheckDisposed(); while (true) { var currentHost = hostsIter.Current; if (currentHost == null) { var ex = new NoHostAvailableException(innerExceptions); _logger.Error("All hosts are not responding.", ex); throw ex; } if (currentHost.IsConsiderablyUp) { triedHosts.Add(currentHost.Address); var hostDistance = Policies.LoadBalancingPolicy.Distance(currentHost); RETRY_GET_POOL: if (!_connectionPool.ContainsKey(currentHost.Address)) { _connectionPool.TryAdd(currentHost.Address, new ConcurrentDictionary <Guid, CassandraConnection>()); } ConcurrentDictionary <Guid, CassandraConnection> pool; if (!_connectionPool.TryGetValue(currentHost.Address, out pool)) { goto RETRY_GET_POOL; } // CassandraCounters.SetConnectionsCount(currentHost.Address, pool.Count); foreach (var kv in pool) { CassandraConnection conn = kv.Value; if (!conn.IsHealthy) { CassandraConnection cc; if (pool.TryRemove(conn.Guid, out cc)) { FreeConnection(cc); } } else { if (!conn.IsBusy(_poolingOptions.GetMaxSimultaneousRequestsPerConnectionTreshold(hostDistance))) { streamId = conn.AllocateStreamId(); return(conn); } else { if (pool.Count > _poolingOptions.GetCoreConnectionsPerHost(hostDistance)) { if (conn.IsFree(_poolingOptions.GetMinSimultaneousRequestsPerConnectionTreshold(hostDistance))) { CassandraConnection cc; if (pool.TryRemove(conn.Guid, out cc)) { TrashcanPut(cc); } } } } } } { var conn = TrashcanRecycle(currentHost.Address); if (conn != null) { if (!conn.IsHealthy) { FreeConnection(conn); } else { pool.TryAdd(conn.Guid, conn); streamId = conn.AllocateStreamId(); return(conn); } } // if not recycled { Exception outExc; conn = AllocateConnection(currentHost.Address, hostDistance, out outExc); if (conn != null) { if (_cluster.Metadata != null) { _cluster.Metadata.BringUpHost(currentHost.Address, this); } pool.TryAdd(conn.Guid, conn); streamId = conn.AllocateStreamId(); return(conn); } else { if (!innerExceptions.ContainsKey(currentHost.Address)) { innerExceptions.Add(currentHost.Address, new List <Exception>()); } innerExceptions[currentHost.Address].Add(outExc); _logger.Info("New connection attempt failed - goto another host."); } } } } _logger.Verbose(string.Format("Currently tried host: {0} have all of connections busy. Switching to the next host.", currentHost.Address)); if (!hostsIter.MoveNext()) { var ex = new NoHostAvailableException(innerExceptions); _logger.Error("Cannot connect to any host from pool.", ex); throw ex; } } }