Beispiel #1
0
        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);
        }
Beispiel #2
0
        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;
                    }
                }
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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;
        }
Beispiel #5
0
        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;
                }
            }
        }