override public void Complete(Session owner, object value, Exception exc = null) { try { var ar = LongActionAc as AsyncResult <RowSet>; if (exc != null) { ar.Complete(exc); } else { RowSet rowset = value as RowSet; if (rowset == null) { rowset = new RowSet(null, owner, false); } rowset.Info.SetTriedHosts(TriedHosts); rowset.Info.SetAchievedConsistency(Consistency); ar.SetResult(rowset); ar.Complete(); } } finally { var ts = StartedAt.ElapsedTicks; CassandraCounters.IncrementCqlQueryCount(); CassandraCounters.IncrementCqlQueryBeats((ts * 1000000000)); CassandraCounters.UpdateQueryTimeRollingAvrg((ts * 1000000000) / Stopwatch.Frequency); CassandraCounters.IncrementCqlQueryBeatsBase(); } }
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; } } } }