예제 #1
0
        /// <inheritdoc />
        public Task <PreparedStatement> PrepareAsync(string query)
        {
            var request = new PrepareRequest(BinaryProtocolVersion, query);

            return(new RequestHandler <PreparedStatement>(this, request, null)
                   .Send()
                   .Continue(SetPrepareTableInfo));
        }
예제 #2
0
        /// <inheritdoc />
        public async Task <PreparedStatement> PrepareAsync(string query, IDictionary <string, byte[]> customPayload)
        {
            var request = new PrepareRequest(query)
            {
                Payload = customPayload
            };

            return(await PrepareHandler.Prepare(this, _serializer, request).ConfigureAwait(false));
        }
예제 #3
0
        private async Task ReprepareAllQueries(Host host)
        {
            ICollection <PreparedStatement> preparedQueries = InternalRef.PreparedQueries.Values;
            IEnumerable <IInternalSession>  sessions        = _connectedSessions;

            if (preparedQueries.Count == 0)
            {
                return;
            }

            // Get the first pool for that host that has open connections
            var pool = sessions.Select(s => s.GetExistingPool(host.Address)).Where(p => p != null).FirstOrDefault(p => p.HasConnections);

            if (pool == null)
            {
                PrepareHandler.Logger.Info($"Not re-preparing queries on {host.Address} as there wasn't an open connection to the node.");
                return;
            }

            PrepareHandler.Logger.Info($"Re-preparing {preparedQueries.Count} queries on {host.Address}");
            var tasks      = new List <Task>(preparedQueries.Count);
            var handler    = InternalRef.Configuration.PrepareHandlerFactory.CreateReprepareHandler();
            var serializer = _metadata.ControlConnection.Serializer.GetCurrentSerializer();

            using (var semaphore = new SemaphoreSlim(64, 64))
            {
                foreach (var ps in preparedQueries)
                {
                    var request = new PrepareRequest(serializer, ps.Cql, ps.Keyspace, null);
                    await semaphore.WaitAsync().ConfigureAwait(false);

                    tasks.Add(Task.Run(() => handler.ReprepareOnSingleNodeAsync(
                                           new KeyValuePair <Host, IHostConnectionPool>(host, pool),
                                           ps,
                                           request,
                                           semaphore,
                                           true)));
                }

                try
                {
                    await Task.WhenAll(tasks).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    PrepareHandler.Logger.Info(
                        "There was an error when re-preparing queries on {0}. " +
                        "The driver will re-prepare the queries individually the next time they are sent to this node. " +
                        "Exception: {1}",
                        host.Address,
                        ex);
                }
            }
        }
예제 #4
0
        /// <inheritdoc />
        public Task <PreparedStatement> PrepareAsync(string query, IDictionary <string, byte[]> customPayload)
        {
            var request = new PrepareRequest(query)
            {
                Payload = customPayload
            };

            return(new RequestHandler <PreparedStatement>(this, _serializer, request)
                   .Send()
                   .Then(SetPrepareTableInfo));
        }
예제 #5
0
        public Task <PreparedStatement> PrepareAsync(string query, IDictionary <string, byte[]> customPayload)
        {
            var request = new PrepareRequest(BinaryProtocolVersion, query)
            {
                Payload = customPayload
            };

            return(new RequestHandler <PreparedStatement>(this, request)
                   .Send()
                   .Continue(SetPrepareTableInfo));
        }
예제 #6
0
        /// <inheritdoc />
        public async Task <PreparedStatement> PrepareAsync(string query, IDictionary <string, byte[]> customPayload)
        {
            var request = new PrepareRequest(query)
            {
                Payload = customPayload
            };
            var handler = new RequestHandler <PreparedStatement>(this, _serializer, request);
            var ps      = await handler.Send().ConfigureAwait(false);

            await SetPrepareTableInfo(ps).ConfigureAwait(false);

            return(ps);
        }
예제 #7
0
        /// <inheritdoc />
        async Task <PreparedStatement> IInternalCluster.Prepare(
            IInternalSession session, ISerializer serializer, PrepareRequest request)
        {
            var lbp     = session.Cluster.Configuration.DefaultRequestOptions.LoadBalancingPolicy;
            var handler = InternalRef.Configuration.PrepareHandlerFactory.CreatePrepareHandler(serializer, this);
            var ps      = await handler.Prepare(request, session, lbp.NewQueryPlan(session.Keyspace, null).GetEnumerator()).ConfigureAwait(false);

            var psAdded = InternalRef.PreparedQueries.GetOrAdd(ps.Id, ps);

            if (ps != psAdded)
            {
                PrepareHandler.Logger.Warning("Re-preparing already prepared query is generally an anti-pattern and will likely " +
                                              "affect performance. Consider preparing the statement only once. Query='{0}'", ps.Cql);
                ps = psAdded;
            }

            return(ps);
        }
예제 #8
0
        private void PrepareAndRetry(byte[] id)
        {
            _logger.Info(String.Format("Query {0} is not prepared on {1}, preparing before retrying executing.", BitConverter.ToString(id), _currentHost.Address));
            BoundStatement boundStatement = null;

            if (_statement is BoundStatement)
            {
                boundStatement = (BoundStatement)_statement;
            }
            else if (_statement is BatchStatement)
            {
                var batch = (BatchStatement)_statement;
                Func <Statement, bool> search = s => s is BoundStatement && ((BoundStatement)s).PreparedStatement.Id.SequenceEqual(id);
                boundStatement = (BoundStatement)batch.Queries.FirstOrDefault(search);
            }
            if (boundStatement == null)
            {
                throw new DriverInternalError("Expected Bound or batch statement");
            }
            var request = new PrepareRequest(_request.ProtocolVersion, boundStatement.PreparedStatement.Cql);

            _connection.Send(request, ResponseReprepareHandler);
        }
예제 #9
0
        private void PrepareAndRetry(byte[] id)
        {
            _logger.Info(String.Format("Query {0} is not prepared on {1}, preparing before retrying executing.", BitConverter.ToString(id), Host.Address));
            BoundStatement boundStatement = null;

            if (_statement is BoundStatement)
            {
                boundStatement = (BoundStatement)_statement;
            }
            else if (_statement is BatchStatement)
            {
                var batch = (BatchStatement)_statement;
                Func <Statement, bool> search = s => s is BoundStatement && ((BoundStatement)s).PreparedStatement.Id.SequenceEqual(id);
                boundStatement = (BoundStatement)batch.Queries.FirstOrDefault(search);
            }
            if (boundStatement == null)
            {
                throw new DriverInternalError("Expected Bound or batch statement");
            }
            var request = new PrepareRequest(_request.ProtocolVersion, boundStatement.PreparedStatement.Cql);

            if (boundStatement.PreparedStatement.Keyspace != null && _session.Keyspace != boundStatement.PreparedStatement.Keyspace)
            {
                _logger.Warning(String.Format("The statement was prepared using another keyspace, changing the keyspace temporarily to" +
                                              " {0} and back to {1}. Use keyspace and table identifiers in your queries and avoid switching keyspaces.",
                                              boundStatement.PreparedStatement.Keyspace, _session.Keyspace));
                //Use the current task scheduler to avoid blocking on a io worker thread
                Task.Factory.StartNew(() =>
                {
                    //Change the keyspace is a blocking operation
                    _connection.Keyspace = boundStatement.PreparedStatement.Keyspace;
                    _connection.Send(request, ResponseReprepareHandler);
                });
                return;
            }
            _connection.Send(request, ResponseReprepareHandler);
        }
예제 #10
0
 public Task<PreparedStatement> PrepareAsync(string query, IDictionary<string, byte[]> customPayload)
 {
     var request = new PrepareRequest(BinaryProtocolVersion, query)
     {
         Payload = customPayload
     };
     return new RequestHandler<PreparedStatement>(this, request, null)
         .Send()
         .Continue(SetPrepareTableInfo);
 }
예제 #11
0
 /// <inheritdoc />
 public Task<PreparedStatement> PrepareAsync(string query)
 {
     var request = new PrepareRequest(BinaryProtocolVersion, query);
     return new RequestHandler<PreparedStatement>(this, request, null)
         .Send()
         .Continue(SetPrepareTableInfo);
 }
예제 #12
0
 public Task<PreparedStatement> PrepareAsync(string query)
 {
     var request = new PrepareRequest(this.BinaryProtocolVersion, query);
     return new RequestHandler<PreparedStatement>(this, request, null).Send();
 }