Beispiel #1
0
 void ExecConn(RequestHandler handler, bool moveNext)
 {
     while (true)
     {
         try
         {
             int streamId;
             handler.Connect(this, moveNext, out streamId);
             handler.Begin(this, streamId);
             return;
         }
         catch (Exception ex)
         {
             if (!CassandraConnection.IsStreamRelatedException(ex))
             {
                 handler.Complete(this, null, ex);
                 return;
             }
             else if (_alreadyDisposed.IsTaken())
             {
                 return;
             }
         }
     }
 }
 internal bool RefreshHosts()
 {
     lock (this)
     {
         try
         {
             if (!_isDiconnected)
             {
                 RefreshNodeListAndTokenMap();
                 return(true);
             }
             return(false);
         }
         catch (NoHostAvailableException)
         {
             _logger.Error("ControlConnection is lost now.");
             return(false);
         }
         catch (Exception ex)
         {
             if (CassandraConnection.IsStreamRelatedException(ex))
             {
                 _logger.Error("ControlConnection is lost now.");
                 return(false);
             }
             else
             {
                 _logger.Error("Unexpected error occurred during forced ControlConnection refresh.", ex);
                 throw;
             }
         }
     }
 }
Beispiel #3
0
            virtual public void Connect(Session owner, bool moveNext, out int streamId)
            {
                if (_hostsIter == null)
                {
                    _hostsIter = owner._policies.LoadBalancingPolicy.NewQueryPlan(Query).GetEnumerator();
                    if (!_hostsIter.MoveNext())
                    {
                        var ex = new NoHostAvailableException(new Dictionary <IPAddress, List <Exception> >());
                        _logger.Error(ex);
                        throw ex;
                    }
                }
                else
                {
                    if (moveNext)
                    {
                        if (!_hostsIter.MoveNext())
                        {
                            var ex = new NoHostAvailableException(InnerExceptions);
                            _logger.Error(ex);
                            throw ex;
                        }
                    }
                }

                Connection = owner.Connect(Query, _hostsIter, TriedHosts, InnerExceptions, out streamId);
            }
Beispiel #4
0
        void FreeConnection(CassandraConnection connection)
        {
            connection.Dispose();
            AtomicValue <int> val;

            _allocatedConnections.TryGetValue(connection.GetHostAdress(), out val);
            var no = Interlocked.Decrement(ref val.RawValue);
        }
        void ClbNoQuery(IAsyncResult ar)
        {
            var token = ar.AsyncState as LongToken;

            try
            {
                try
                {
                    object value;
                    token.Process(this, ar, out value);
                    token.Complete(this, value);
                }
                catch (QueryValidationException exc)
                {
                    var decision = GetRetryDecision(token.Query, exc, _policies.RetryPolicy, token.QueryRetries);
                    if (decision == null)
                    {
                        token.InnerExceptions[token.Connection.GetHostAdress()] = exc;
                        ExecConn(token, true);
                    }
                    else
                    {
                        switch (decision.DecisionType)
                        {
                        case RetryDecision.RetryDecisionType.Rethrow:
                            token.Complete(this, null, exc);
                            return;

                        case RetryDecision.RetryDecisionType.Retry:
                            token.Consistency = decision.RetryConsistencyLevel ?? token.Consistency;
                            token.QueryRetries++;
                            token.InnerExceptions[token.Connection.GetHostAdress()] = exc;
                            ExecConn(token, false);
                            return;

                        default:
                            token.Complete(this, null);
                            return;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (CassandraConnection.IsStreamRelatedException(ex))
                {
                    token.InnerExceptions[token.Connection.GetHostAdress()] = ex;
                    ExecConn(token, true);
                }
                else
                {
                    token.Complete(this, null, ex);
                }
            }
        }
        private void SetupControlConnection(bool refreshOnly = false)
        {
            lock (this)
            {
                try
                {
                    _reconnectionTimer.Change(Timeout.Infinite, Timeout.Infinite);
                    _logger.Info("Refreshing ControlConnection...");
                    if (!refreshOnly)
                    {
                        Monitor.Exit(this);
                        try
                        {
                            SetupEventListener();
                        }
                        finally
                        {
                            Monitor.Enter(this);
                        }
                    }
                    RefreshNodeListAndTokenMap();
                    _isDiconnected = false;
                    _logger.Info("ControlConnection is fresh!");
                }
                catch (NoHostAvailableException)
                {
                    _isDiconnected = true;
                    if (!shotDown.IsTaken())
                    {
                        _logger.Error("ControlConnection is lost. Retrying..");
                        _reconnectionTimer.Change(_reconnectionSchedule.NextDelayMs(), Timeout.Infinite);
                    }
                }
                catch (Exception ex)
                {
                    _isDiconnected = true;
                    if (CassandraConnection.IsStreamRelatedException(ex))
                    {
                        if (!shotDown.IsTaken())
                        {
                            _logger.Error("ControlConnection is lost. Retrying..");
                            _reconnectionTimer.Change(_reconnectionSchedule.NextDelayMs(), Timeout.Infinite);
                        }
                    }
                    else
                    {
                        _logger.Error("Unexpected error occurred during ControlConnection refresh.", ex);
//                        throw;
                    }
                }
            }
        }
Beispiel #7
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 #8
0
        void TrashcanPut(CassandraConnection conn)
        {
RETRY:
            if (!_trashcan.ContainsKey(conn.GetHostAdress()))
            {
                _trashcan.TryAdd(conn.GetHostAdress(), new ConcurrentDictionary <Guid, CassandraConnection>());
            }

            ConcurrentDictionary <Guid, CassandraConnection> trashes;

            if (_trashcan.TryGetValue(conn.GetHostAdress(), out trashes))
            {
                trashes.TryAdd(conn.Guid, conn);
            }
            else
            {
                goto RETRY;
            }

            _trashcanCleaner.Change(10000, Timeout.Infinite);
        }
 void ExecConn(LongToken token, bool moveNext)
 {
     while (true)
     {
         try
         {
             token.Connect(this, moveNext);
             token.Begin(this);
             return;
         }
         catch (Exception ex)
         {
             if (!CassandraConnection.IsStreamRelatedException(ex))
             {
                 token.Complete(this, null, ex);
                 return;
             }
             //else
             //retry
         }
     }
 }
Beispiel #10
0
            public virtual void Connect(Session owner, bool moveNext, out int streamId)
            {
                if (_hostsIter == null)
                {
                    _hostsIter = owner._policies.LoadBalancingPolicy.NewQueryPlan(Query).GetEnumerator();
                    if (!_hostsIter.MoveNext())
                    {
                        var ex = new NoHostAvailableException(new Dictionary<IPAddress, List<Exception>>());
                        _logger.Error(ex);
                        throw ex;
                    }
                }
                else
                {
                    if (moveNext)
                        if (!_hostsIter.MoveNext())
                        {
                            var ex = new NoHostAvailableException(InnerExceptions);
                            _logger.Error(ex);
                            throw ex;
                        }
                }

                Connection = owner.Connect(_hostsIter, TriedHosts, InnerExceptions, out streamId);
            }
Beispiel #11
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);
        }
        private void SetupEventListeners(CassandraConnection nconn)
        {
            Exception theExc = null;

            nconn.CassandraEvent += new CassandraEventHandler(conn_CassandraEvent);
            using (var ret = nconn.RegisterForCassandraEvent(
                CassandraEventType.TopologyChange | CassandraEventType.StatusChange | CassandraEventType.SchemaChange))
            {
                if (!(ret is OutputVoid))
                {
                    if (ret is OutputError)
                        theExc = (ret as OutputError).CreateException();
                    else
                        theExc = new DriverInternalError("Expected Error on Output");
                }
            }

            if (theExc != null)
            {
                _logger.Error(theExc);
                throw theExc;
            }
        }
        private void RefreshNodeListAndTokenMap(CassandraConnection connection)
        {
            _logger.Info("Refreshing NodeList and TokenMap..");
            // Make sure we're up to date on nodes and tokens
            var tokenMap = new Dictionary<IPAddress, DictSet<string>>();
            string partitioner = null;

            using (var rowset = _session.Query(SelectLocal, ConsistencyLevel.Default))
            {
                // Update cluster name, DC and rack for the one node we are connected to
                foreach (var localRow in rowset.GetRows())
                {
                    var clusterName = localRow.GetValue<string>("cluster_name");
                    if (clusterName != null)
                        _cluster.Metadata.ClusterName = clusterName;

                    var host = _cluster.Metadata.GetHost(connection.GetHostAdress());
                    // In theory host can't be null. However there is no point in risking a NPE in case we
                    // have a race between a node removal and this.
                    if (host != null)
                    {
                        host.SetLocationInfo(localRow.GetValue<string>("data_center"), localRow.GetValue<string>("rack"));

                        partitioner = localRow.GetValue<string>("partitioner");
                        var tokens = localRow.GetValue<IList<string>>("tokens");
                        if (partitioner != null && tokens.Count > 0)
                        {
                            if (!tokenMap.ContainsKey(host.Address))
                                tokenMap.Add(host.Address, new DictSet<string>());
                            tokenMap[host.Address].AddRange(tokens);
                        }
                    }
                    break;
                }
            }

            var foundHosts = new List<IPAddress>();
            var dcs = new List<string>();
            var racks = new List<string>();
            var allTokens = new List<DictSet<string>>();

            using (var rowset = _session.Query(SelectPeers, ConsistencyLevel.Default))
            {
                foreach (var row in rowset.GetRows())
                {
                    var hstip = row.GetValue<IPEndPoint>("peer").Address;
                    if (hstip != null)
                    {
                        foundHosts.Add(hstip);
                        dcs.Add(row.GetValue<string>("data_center"));
                        racks.Add(row.GetValue<string>("rack"));
                        allTokens.Add(new DictSet<string>(row.GetValue<IEnumerable<string>>("tokens")));
                    }
                }
            }

            for (int i = 0; i < foundHosts.Count; i++)
            {
                var host = _cluster.Metadata.GetHost(foundHosts[i]);
                if (host == null)
                {
                    // We don't know that node, add it.
                    host = _cluster.Metadata.AddHost(foundHosts[i], _session._policies.ReconnectionPolicy);
                }
                host.SetLocationInfo(dcs[i], racks[i]);

                if (partitioner != null && !allTokens[i].IsEmpty)
                    tokenMap.Add(host.Address, allTokens[i]);
            }

            // Removes all those that seems to have been removed (since we lost the control connection)
            var foundHostsSet = new DictSet<IPAddress>(foundHosts);
            foreach (var host in _cluster.Metadata.AllReplicas())
                if (!host.Equals(connection.GetHostAdress()) && !foundHostsSet.Contains(host))
                    _cluster.Metadata.RemoveHost(host);

            if (partitioner != null)
                _cluster.Metadata.RebuildTokenMap(partitioner, tokenMap);
            _logger.Info("NodeList and TokenMap have been successfully refreshed!");
        }
        private void Go(bool refresh)
        {
            lock (this)
            {
                try
                {
                    if (_hostsIter == null)
                    {
                        _logger.Info("Retrieving hosts list.");
                        _hostsIter = _session._policies.LoadBalancingPolicy.NewQueryPlan(null).GetEnumerator();
                    }

                    if (!_hostsIter.MoveNext())
                    {
                        _isDiconnected = true;
                        _hostsIter = null;
                        _reconnectionTimer.Change(_reconnectionSchedule.NextDelayMs(), Timeout.Infinite);
                    }
                    else
                    {
                        _logger.Info("Establishing ControlConnection...");
                        _reconnectionTimer.Change(Timeout.Infinite, Timeout.Infinite);
                        var triedHosts = new List<IPAddress>();
                        var innerExceptions = new Dictionary<IPAddress, Exception>();
                        _connection = _session.Connect(null, _hostsIter, triedHosts, innerExceptions);
                        SetupEventListeners(_connection);
                        if (refresh)
                            RefreshNodeListAndTokenMap(_connection);
                        _logger.Info("ControlConnection has been established!");
                    }
                }
                catch (NoHostAvailableException)
                {
                    _logger.Error("Cannot connect to any host. Retrying..");
                    _isDiconnected = true;
                    _hostsIter = null;
                    _reconnectionTimer.Change(_reconnectionSchedule.NextDelayMs(), Timeout.Infinite);
                }
                catch (Exception ex)
                {
                    if (CassandraConnection.IsStreamRelatedException(ex))
                    {
                        _isDiconnected = true;
                        _hostsIter = null;
                        _reconnectionTimer.Change(_reconnectionSchedule.NextDelayMs(), Timeout.Infinite);
                    }
                    else
                    {
                        _logger.Error("Unexpected error occurred during ControlConnection establishment.", ex);
                        throw;
                    }
                }
            }
        }
Beispiel #15
0
        internal void RequestCallback(IAsyncResult ar)
        {
            var handler = ar.AsyncState as RequestHandler;

            try
            {
                try
                {
                    object value;
                    handler.Process(this, ar, out value);
                    handler.Complete(this, value);
                }
                catch (QueryValidationException exc)
                {
                    var decision = GetRetryDecision(handler.Statement, exc, handler.Statement != null ? (handler.Statement.RetryPolicy ?? Policies.RetryPolicy) : Policies.RetryPolicy, handler.QueryRetries);
                    if (decision == null)
                    {
                        if (!handler.InnerExceptions.ContainsKey(handler.Connection.GetHostAdress()))
                        {
                            handler.InnerExceptions.Add(handler.Connection.GetHostAdress(), new List <Exception>());
                        }

                        handler.InnerExceptions[handler.Connection.GetHostAdress()].Add(exc);
                        ExecConn(handler, true);
                    }
                    else
                    {
                        switch (decision.DecisionType)
                        {
                        case RetryDecision.RetryDecisionType.Rethrow:
                            handler.Complete(this, null, exc);
                            return;

                        case RetryDecision.RetryDecisionType.Retry:
                            if (handler.LongActionAc.IsCompleted)
                            {
                                return;
                            }
                            handler.Consistency = (decision.RetryConsistencyLevel.HasValue && (decision.RetryConsistencyLevel.Value < ConsistencyLevel.Serial)) ? decision.RetryConsistencyLevel.Value : handler.Consistency;
                            handler.QueryRetries++;

                            if (!handler.InnerExceptions.ContainsKey(handler.Connection.GetHostAdress()))
                            {
                                handler.InnerExceptions.Add(handler.Connection.GetHostAdress(), new List <Exception>());
                            }

                            handler.InnerExceptions[handler.Connection.GetHostAdress()].Add(exc);
                            ExecConn(handler, exc is UnavailableException);
                            return;

                        default:
                            handler.Complete(this, null);
                            return;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (CassandraConnection.IsStreamRelatedException(ex))
                {
                    if (!handler.InnerExceptions.ContainsKey(handler.Connection.GetHostAdress()))
                    {
                        handler.InnerExceptions.Add(handler.Connection.GetHostAdress(), new List <Exception>());
                    }
                    handler.InnerExceptions[handler.Connection.GetHostAdress()].Add(ex);
                    ExecConn(handler, true);
                }
                else
                {
                    handler.Complete(this, null, ex);
                }
            }
        }
Beispiel #16
0
 public void Connect(string username, string password, string apiKey)
 {
     if (Config.Settings.ContainsKey("PUBLISHING_START_TIME"))
         _startTime = Config.ParseDateTimeLocal(Config.Settings["PUBLISHING_START_TIME"]);
     if (Config.Settings.ContainsKey("PUBLISHING_STOP_TIME"))
         _stopTime = Config.ParseDateTimeLocal(Config.Settings["PUBLISHING_STOP_TIME"]);
     if (Config.Settings.ContainsKey("SAMPLING_MS"))
         _samplingMs = int.Parse(Config.Settings["SAMPLING_MS"]);
     _testReplayFiles.Clear();
     if (Config.Settings.ContainsKey("DELETEDB"))
     {
         _deleteDB = true;
         _testReplayFiles.Add(null); // Add a fake element to trigger the replay from db
         _deleter = new CassandraConnection();
         _reader = _deleter;
         _readerExpectedResults = _deleter;
         _hasExpectedResults = true;
     }
     else
     {
         if (Config.Settings["REPLAY_MODE"] == "DB")
         {
             _testReplayFiles.Add(null); // Add a fake element to trigger the replay from db
             _reader = new CassandraConnection();
         }
         else if (Config.Settings["REPLAY_MODE"] == "CSV")
         {
             if (Config.Settings.ContainsKey("REPLAY_CSV"))
             {
                 _testReplayFiles = Config.Settings["REPLAY_CSV"].Split(';').ToList();
                 if (_reader != null)
                     _reader.CloseConnection();
                 _reader = new CsvReader(_testReplayFiles[0]);
             }
             else
                 _reader = new CsvReader(null);
         }
         else
             _reader = null;
         _hasExpectedResults = Config.TestReplayEnabled || Config.CalibratorEnabled;
         if (_hasExpectedResults)
         {
             if (Config.Settings.ContainsKey("EXPECTEDRESULTS_CSV"))
                 _readerExpectedResults = new CsvReader(Config.Settings["EXPECTEDRESULTS_CSV"]);
             else
                 _readerExpectedResults = new CsvReader(_testReplayFiles[0]);
         }
     }
     _numId = 1;
     _numRef = 1;
 }
Beispiel #17
0
        void TrashcanPut(CassandraConnection conn)
        {
            RETRY:
            if (!_trashcan.ContainsKey(conn.GetHostAdress()))
                _trashcan.TryAdd(conn.GetHostAdress(), new ConcurrentDictionary<Guid, CassandraConnection>());

            ConcurrentDictionary<Guid, CassandraConnection> trashes;
            if (_trashcan.TryGetValue(conn.GetHostAdress(), out trashes))
                trashes.TryAdd(conn.Guid,conn);
            else
                goto RETRY;

            _trashcanCleaner.Change(10000, Timeout.Infinite);
        }
Beispiel #18
0
 void FreeConnection(CassandraConnection connection)
 {
     connection.Dispose();
     AtomicValue<int> val;
     _allocatedConnections.TryGetValue(connection.GetHostAdress(), out val);
     var no = Interlocked.Decrement(ref val.RawValue);
 }
Beispiel #19
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;
                }
            }
        }
Beispiel #20
0
        void ClbNoQuery(IAsyncResult ar)
        {
            var token = ar.AsyncState as LongToken;

            try
            {
                try
                {
                    object value;
                    token.Process(this, ar, out value);
                    token.Complete(this, value);
                }
                catch (QueryValidationException exc)
                {
                    var decision = GetRetryDecision(token.Query, exc, token.Query != null ? (token.Query.RetryPolicy ?? _policies.RetryPolicy) : _policies.RetryPolicy, token.QueryRetries);
                    if (decision == null)
                    {
                        if (!token.InnerExceptions.ContainsKey(token.Connection.GetHostAdress()))
                        {
                            token.InnerExceptions.Add(token.Connection.GetHostAdress(), new List <Exception>());
                        }

                        token.InnerExceptions[token.Connection.GetHostAdress()].Add(exc);
                        ExecConn(token, true);
                    }
                    else
                    {
                        switch (decision.DecisionType)
                        {
                        case RetryDecision.RetryDecisionType.Rethrow:
                            token.Complete(this, null, exc);
                            return;

                        case RetryDecision.RetryDecisionType.Retry:
                            if (token.LongActionAc.IsCompleted)
                            {
                                return;
                            }
                            token.Consistency = decision.RetryConsistencyLevel.HasValue ? decision.RetryConsistencyLevel.Value : token.Consistency;
                            token.QueryRetries++;

                            if (!token.InnerExceptions.ContainsKey(token.Connection.GetHostAdress()))
                            {
                                token.InnerExceptions.Add(token.Connection.GetHostAdress(), new List <Exception>());
                            }

                            token.InnerExceptions[token.Connection.GetHostAdress()].Add(exc);
                            ExecConn(token, false);
                            return;

                        default:
                            token.Complete(this, null);
                            return;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (CassandraConnection.IsStreamRelatedException(ex))
                {
                    if (!token.InnerExceptions.ContainsKey(token.Connection.GetHostAdress()))
                    {
                        token.InnerExceptions.Add(token.Connection.GetHostAdress(), new List <Exception>());
                    }
                    token.InnerExceptions[token.Connection.GetHostAdress()].Add(ex);
                    ExecConn(token, true);
                }
                else
                {
                    token.Complete(this, null, ex);
                }
            }
        }
Beispiel #21
0
        CassandraConnection AllocateConnection(IPAddress endPoint, out Exception outExc)
        {
            CassandraConnection nconn = null;
            outExc = null;

            try
            {
                nconn = new CassandraConnection(this, endPoint, _protocolOptions, _socketOptions, _clientOptions, _authProvider);

                var options = nconn.ExecuteOptions();

                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 #22
0
        CassandraConnection AllocateConnection(IPAddress endPoint, out Exception outExc)
        {
            CassandraConnection nconn = null;
            outExc = null;

            try
            {
                nconn = new CassandraConnection(this, endPoint, _protocolOptions, _socketOptions, _clientOptions, _authProvider);

                var options = nconn.ExecuteOptions();

                if (!string.IsNullOrEmpty(_keyspace))
                {
                    var keyspaceId = CqlQueryTools.CqlIdentifier(_keyspace);
                    string retKeyspaceId;
                    try
                    {
                        retKeyspaceId = ProcessSetKeyspace(nconn.Query(GetUseKeyspaceCQL(keyspaceId), ConsistencyLevel.Ignore,false));
                    }
                    catch (InvalidException)
                    {
                        throw;
                    }
                    catch (QueryValidationException)
                    {
                        return null;
                    }

                    if (CqlQueryTools.CqlIdentifier(retKeyspaceId) != CqlQueryTools.CqlIdentifier(keyspaceId))
                    {
                        var ex = new DriverInternalError("USE query returned " + retKeyspaceId + ". We expected " + keyspaceId + ".");
                        _logger.Error(ex);
                        throw ex;
                    }

                    lock(_preparedQueries)
                        foreach (var prepQ in _preparedQueries)
                        {
                            try
                            {
                                byte[] queryid;
                                RowSetMetadata metadata;
                                ProcessPrepareQuery(nconn.PrepareQuery(prepQ.Key), out metadata, out queryid);
                            }
                            catch (QueryValidationException)
                            {
                                return null;
                            }
                            //TODO: makesure that ids are equal;
                        }
                }
            }
            catch (Exception ex)
            {
                if (nconn != null)
                    nconn.Dispose();

                if (CassandraConnection.IsStreamRelatedException(ex))
                {
                    outExc = ex;
                    return null;
                }
                else
                    throw ex;
            }

            _logger.Info("Allocated new connection");

            return nconn;
        }
Beispiel #23
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 #24
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;
        }