Пример #1
0
        public async Task <T> RunAsync <T>(IQueryConverter queryConverter, IScalarQuery <T> queryObject, CancellationToken cancellationToken)
        {
            var query = new Spec.Query();

            query.token = GetNextToken();
            query.type  = Spec.Query.QueryType.START;
            query.query = queryObject.GenerateTerm(queryConverter);

            var response = await InternalRunQuery(query, cancellationToken);

            switch (response.type)
            {
            case Response.ResponseType.SUCCESS_SEQUENCE:
            case Response.ResponseType.SUCCESS_ATOM:
                if (response.response.Count != 1)
                {
                    throw new RethinkDbRuntimeException(String.Format("Expected 1 object, received {0}", response.response.Count));
                }
                return(queryConverter.Get <T>().ConvertDatum(response.response[0]));

            case Response.ResponseType.CLIENT_ERROR:
            case Response.ResponseType.COMPILE_ERROR:
                throw new RethinkDbInternalErrorException("Client error: " + response.response[0].r_str);

            case Response.ResponseType.RUNTIME_ERROR:
                throw new RethinkDbRuntimeException("Runtime error: " + response.response[0].r_str);

            default:
                throw new RethinkDbInternalErrorException("Unhandled response type: " + response.type);
            }
        }
Пример #2
0
 public void Reset()
 {
     query             = null;
     lastResponse      = null;
     lastResponseIndex = 0;
     disposed          = false;
 }
Пример #3
0
        internal async Task <Response> InternalRunQuery(Spec.Query query, CancellationToken cancellationToken)
        {
            var tcs = new TaskCompletionSource <Response>();

            tokenResponse[query.token] = tcs;

            DateTime start = DateTime.UtcNow;

            Logger.Debug("InternalRunQuery: beginning process of transmitting query w/ token {0}", query.token);
            bool pastSpinLock = false;

            Action abortToken = () => {
                DateTime timeout = DateTime.UtcNow;
                if (!pastSpinLock)
                {
                    Logger.Warning(
                        "Query token {0} timed out after {1}; usually this happens because of a query timeout, but, query never acquired write lock on the connection in before timing out.  Write lock is currently held by query token {2}.",
                        query.token,
                        timeout - start,
                        writeTokenLock);
                }
                else
                {
                    Logger.Warning(
                        "Query token {0} timed out after {1} because CancellationToken was triggered; usually this happens because of a query timeout.",
                        query.token,
                        timeout - start);
                }
                if (tokenResponse.Remove(query.token))
                {
                    tcs.SetCanceled();
                }
            };

            using (cancellationToken.Register(abortToken))
            {
                // Put query.token into writeTokenLock if writeTokenLock is 0 (ie. unlocked).  If it's not 0,
                // spin-lock on the compare exchange.
                while (Interlocked.CompareExchange(ref writeTokenLock, query.token, 0) != 0)
                {
                    ;
                }

                try
                {
                    Logger.Debug("InternalRunQuery: acquired write lock for query token {0}", query.token);
                    pastSpinLock = true;
                    Logger.Debug("InternalRunQuery: writing query token {0}", query.token);
                    await Protocol.WriteQueryToStream(stream, Logger, query, cancellationToken);
                }
                finally
                {
                    // Revert writeTokenLock to 0.
                    writeTokenLock = 0;
                }

                Logger.Debug("InternalRunQuery: waiting for response for query token {0}", query.token);
                return(await tcs.Task);
            }
        }
Пример #4
0
        internal async Task <Response> InternalRunQuery(Spec.Query query, CancellationToken cancellationToken)
        {
            var tcs = new TaskCompletionSource <Response>();

            tokenResponse[query.token] = tcs;

            Action abortToken = () => {
                Logger.Warning("Query token {0} timed out after {1}", query.token, this.QueryTimeout);
                if (tokenResponse.Remove(query.token))
                {
                    tcs.SetCanceled();
                }
            };

            using (cancellationToken.Register(abortToken))
            {
                using (var memoryBuffer = new MemoryStream(1024))
                {
                    Serializer.Serialize(memoryBuffer, query);

                    var data   = memoryBuffer.ToArray();
                    var header = BitConverter.GetBytes(data.Length);
                    if (!BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(header, 0, header.Length);
                    }

                    // Put query.token into writeTokenLock if writeTokenLock is 0 (ie. unlocked).  If it's not 0,
                    // spin-lock on the compare exchange.
                    while (Interlocked.CompareExchange(ref writeTokenLock, (long)query.token, 0) != 0)
                    {
                        ;
                    }

                    try
                    {
                        Logger.Debug("Writing packet, {0} bytes", data.Length);
                        await stream.WriteAsync(header, 0, header.Length, cancellationToken);

                        await stream.WriteAsync(data, 0, data.Length, cancellationToken);
                    }
                    finally
                    {
                        // Revert writeTokenLock to 0.
                        writeTokenLock = 0;
                    }
                }

                return(await tcs.Task);
            }
        }
Пример #5
0
            public async Task <bool> MoveNext(CancellationToken cancellationToken)
            {
                if (disposed)
                {
                    throw new ObjectDisposedException(GetType().FullName);
                }

                if (lastResponse == null)
                {
                    query       = new Spec.Query();
                    query.token = connection.GetNextToken();
                    connection.Logger.Debug("QueryEnumerator: Token {0} is assigned to query {1}", query.token, queryObject);
                    query.type  = Spec.Query.QueryType.START;
                    query.query = this.queryObject.GenerateTerm(queryConverter);
                    await ReissueQuery(cancellationToken);
                }

                if (lastResponseIndex < (LoadedRecordCount() - 1))
                {
                    lastResponseIndex += 1;
                    return(true);
                }

                if (lastResponse.type == Response.ResponseType.SUCCESS_SEQUENCE ||
                    lastResponse.type == Response.ResponseType.SUCCESS_ATOM)
                {
                    return(false);
                }
                else if (lastResponse.type == Response.ResponseType.SUCCESS_PARTIAL ||
                         lastResponse.type == (Response.ResponseType) 5)
                {
                    query.type  = RethinkDb.Spec.Query.QueryType.CONTINUE;
                    query.query = null;
                    await ReissueQuery(cancellationToken);

                    return(await MoveNext(cancellationToken));
                }
                else
                {
                    throw new RethinkDbInternalErrorException("Unreachable code; ReissueQuery should prevent reaching this condition");
                }
            }
Пример #6
0
        internal async Task <Response> InternalRunQuery(Spec.Query query, CancellationToken cancellationToken)
        {
            var tcs = new TaskCompletionSource <Response>();

            tokenResponse[query.token] = tcs;

            Action abortToken = () => {
                Logger.Warning("Query token {0} timed out after {1}", query.token, this.QueryTimeout);
                if (tokenResponse.Remove(query.token))
                {
                    tcs.SetCanceled();
                }
            };

            using (cancellationToken.Register(abortToken))
            {
                // Put query.token into writeTokenLock if writeTokenLock is 0 (ie. unlocked).  If it's not 0,
                // spin-lock on the compare exchange.
                while (Interlocked.CompareExchange(ref writeTokenLock, query.token, 0) != 0)
                {
                    ;
                }

                try
                {
                    await Protocol.WriteQueryToStream(stream, Logger, query, cancellationToken);
                }
                finally
                {
                    // Revert writeTokenLock to 0.
                    writeTokenLock = 0;
                }

                return(await tcs.Task);
            }
        }