示例#1
0
        public void WithCancellationToken()
        {
            CancellationToken token1 = new CancellationTokenSource().Token;
            var original             = new CallSettings(token1, Expiration.None, null, null, null, null);

            CancellationToken token2 = new CancellationTokenSource().Token;
            var result = original.WithCancellationToken(token2);

            Assert.Same(Expiration.None, result.Expiration);
            Assert.Equal(token2, result.CancellationToken);
        }
        public void WithCancellationToken()
        {
            CancellationToken token1 = new CancellationTokenSource().Token;
            CallTiming timing = CallTiming.FromExpiration(Expiration.None);
            var original = new CallSettings(token1, null, timing, null, null, null);

            CancellationToken token2 = new CancellationTokenSource().Token;
            var result = original.WithCancellationToken(token2);
            Assert.Same(timing, result.Timing);
            Assert.Equal(token2, result.CancellationToken);
        }
示例#3
0
        public void WithCancellationToken()
        {
            CancellationToken token1 = new CancellationTokenSource().Token;
            CallTiming        timing = CallTiming.FromExpiration(Expiration.None);
            var original             = new CallSettings(token1, null, timing, null, null, null);

            CancellationToken token2 = new CancellationTokenSource().Token;
            var result = original.WithCancellationToken(token2);

            Assert.Same(timing, result.Timing);
            Assert.Equal(token2, result.CancellationToken);
        }
                public async Task <bool> MoveNext(CancellationToken cancellationToken)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    if (_finished)
                    {
                        return(false);
                    }
                    CallSettings effectiveCallSettings = _parent._callSettings;

                    if (cancellationToken != default(CancellationToken))
                    {
                        effectiveCallSettings = effectiveCallSettings.WithCancellationToken(cancellationToken);
                    }
                    var response = await _parent._apiCall.Async(_request, effectiveCallSettings).ConfigureAwait(false);

                    _finished = !MoreResultsAvailable(response);
                    ModifyRequest(_request, response);
                    Current = response;
                    return(true);
                }
        /// <summary>
        /// Fetches document snapshots from the server, based on an optional transaction ID.
        /// </summary>
        /// <param name="documents">The document references to fetch. Must not be null, or contain null references.</param>
        /// <param name="transactionId">A transaction ID, or null to not include any transaction ID.</param>
        /// <param name="fieldMask">The field mask to use to restrict which fields are retrieved. May be null, in which
        /// case no field mask is applied, and the complete documents are retrieved.</param>
        /// <param name="cancellationToken">A cancellation token for the operation.</param>
        /// <returns>The document snapshots, in the order they are provided in the response. (This may not be the order of <paramref name="documents"/>.)</returns>
        internal async Task <IList <DocumentSnapshot> > GetDocumentSnapshotsAsync(IEnumerable <DocumentReference> documents, ByteString transactionId, FieldMask fieldMask, CancellationToken cancellationToken)
        {
            GaxPreconditions.CheckNotNull(documents, nameof(documents));
            var request = new BatchGetDocumentsRequest
            {
                Database  = RootPath,
                Documents = { documents.Select(ExtractPath) },
                Mask      = fieldMask?.ToProto()
            };

            if (transactionId != null)
            {
                request.Transaction = transactionId;
            }

            var clock        = Client.Settings.Clock ?? SystemClock.Instance;
            var scheduler    = Client.Settings.Scheduler ?? SystemScheduler.Instance;
            var callSettings = _batchGetCallSettings.WithCancellationToken(cancellationToken);

            // This is the function that we'll retry. We can't use the built-in retry functionality, because it's not a unary gRPC call.
            // (We could potentially simulate a unary call, but it would be a little odd to do so.)
            // Note that we perform a "whole request" retry. In theory we could collect some documents, then see an error, and only
            // request the remaining documents. Given how rarely we retry anyway in practice, that's probably not worth doing.
            Func <BatchGetDocumentsRequest, CallSettings, Task <List <DocumentSnapshot> > > function = async(req, settings) =>
            {
                var stream = Client.BatchGetDocuments(req, settings);
                using (var responseStream = stream.ResponseStream)
                {
                    List <DocumentSnapshot> snapshots = new List <DocumentSnapshot>();

                    // Note: no need to worry about passing the cancellation token in here, as we've passed it into the overall call.
                    // If the token is cancelled, the call will be aborted.
                    while (await responseStream.MoveNext().ConfigureAwait(false))
                    {
                        var response = responseStream.Current;
                        var readTime = Timestamp.FromProto(response.ReadTime);
                        switch (response.ResultCase)
                        {
                        case BatchGetDocumentsResponse.ResultOneofCase.Found:
                            snapshots.Add(DocumentSnapshot.ForDocument(this, response.Found, readTime));
                            break;

                        case BatchGetDocumentsResponse.ResultOneofCase.Missing:
                            snapshots.Add(DocumentSnapshot.ForMissingDocument(this, response.Missing, readTime));
                            break;

                        default:
                            throw new InvalidOperationException($"Unknown response type: {response.ResultCase}");
                        }
                    }
                    return(snapshots);
                }
            };

            var retryingTask = RetryHelper.Retry(function, request, callSettings, clock, scheduler);

            return(await retryingTask.ConfigureAwait(false));

            string ExtractPath(DocumentReference documentReference)
            {
                GaxPreconditions.CheckArgument(documentReference != null, nameof(documents), "DocumentReference sequence must not contain null elements.");
                return(documentReference.Path);
            }
        }