Ejemplo n.º 1
0
        public async Task MultipleCallsEventualSuccess(bool async, bool serverStreaming)
        {
            var callDuration  = TimeSpan.FromTicks(300);
            var failures      = 4;      // Fifth call will succeed
            var name          = "name"; // Copied from request to response
            var scheduler     = new FakeScheduler();
            var time0         = scheduler.Clock.GetCurrentDateTimeUtc();
            var server        = new Server(failures, callDuration, scheduler);
            var retrySettings = new RetrySettings(
                retryBackoff: DoublingBackoff,
                timeoutBackoff: ConstantBackoff,
                totalExpiration: Expiration.FromTimeout(TimeSpan.FromSeconds(1)),
                retryFilter: null,
                delayJitter: RetrySettings.NoJitter);

            await scheduler.RunAsync(async() =>
            {
                var callSettings = CallSettings.FromCallTiming(CallTiming.FromRetry(retrySettings));
                var request      = new SimpleRequest {
                    Name = name
                };
                var result = await Call(async, serverStreaming, scheduler, server, request, callSettings);
                Assert.Equal(name, result.Name);
            });

            var firstCall  = time0;
            var secondCall = firstCall + callDuration + TimeSpan.FromTicks(1000);  // Delay for 1000 ticks
            var thirdCall  = secondCall + callDuration + TimeSpan.FromTicks(2000); // Delay for 2000 ticks
            var fourthCall = thirdCall + callDuration + TimeSpan.FromTicks(4000);  // Delay for 4000 ticks
            var fifthCall  = fourthCall + callDuration + TimeSpan.FromTicks(5000); // Delay for 5000 ticks, as that's the max

            server.AssertCallTimes(firstCall, secondCall, thirdCall, fourthCall, fifthCall);
            // Time of last action was when the call returned
            Assert.Equal(fifthCall + callDuration, scheduler.Clock.GetCurrentDateTimeUtc());
        }
Ejemplo n.º 2
0
        public async Task RetryFilter_EventualSuccess(bool async, StatusCode failureCode, StatusCode[] filterCodes)
        {
            var callDuration = 100;
            var failures     = 1;
            var scheduler    = new FakeScheduler();
            var server       = new Server(failures, callDuration, scheduler, failureCode);
            // We're not really interested in the timing in this test.
            var retrySettings = new RetrySettings(
                retryBackoff: ConstantBackoff,
                timeoutBackoff: ConstantBackoff,
                delayJitter: RetrySettings.NoJitter,
                totalExpiration: Expiration.FromTimeout(TimeSpan.FromSeconds(1)),
                retryFilter: RetrySettings.FilterForStatusCodes(filterCodes));

            await scheduler.RunAsync(async() =>
            {
                var callSettings     = CallSettings.FromCallTiming(CallTiming.FromRetry(retrySettings));
                var retryingCallable = server.Callable.WithRetry(scheduler.Clock, scheduler);
                await Call(async, retryingCallable, new SimpleRequest {
                    Name = "irrelevant"
                }, callSettings);
            });

            Assert.True(server.CallTimes.Count() > 1);
        }
Ejemplo n.º 3
0
        private async Task process()
        {
            InitializeQueue();

            var response = await _sub.PullAsync(_subscriptionName, false, 1,
                                                CallSettings.FromCallTiming(
                                                    CallTiming.FromExpiration(
                                                        Expiration.FromTimeout(
                                                            TimeSpan.FromSeconds(90)))));

            if (response.ReceivedMessages == null || response.ReceivedMessages.Count == 0)
            {
                return;
            }

            var message   = response.ReceivedMessages[0];
            var jsonBytes = message.Message.Data.ToByteArray();
            var payload   = Encoding.UTF8.GetString(jsonBytes);

            _appLogger.LogMessage($"Message Type: {typeof(T).FullName} dequeued with MessageId: {message.Message.MessageId}");

            _messageHandler(payload);

            await _sub.AcknowledgeAsync(_subscriptionName, new string[] { message.AckId });
        }
Ejemplo n.º 4
0
        public async Task CallSettingsDeadlineIsObserved(bool async, bool serverStreaming)
        {
            var callDuration  = TimeSpan.FromTicks(300);
            var failures      = 4; // Fifth call would succeed, but we won't get that far.
            var scheduler     = new FakeScheduler();
            var time0         = scheduler.Clock.GetCurrentDateTimeUtc();
            var server        = new Server(failures, callDuration, scheduler);
            var callable      = server.Callable;
            var retrySettings = new RetrySettings(
                retryBackoff: DoublingBackoff,
                timeoutBackoff: ConstantBackoff,
                totalExpiration: Expiration.FromTimeout(TimeSpan.FromTicks(2500)),
                retryFilter: null,
                delayJitter: RetrySettings.NoJitter);

            var task = scheduler.RunAsync(async() =>
            {
                // Expiration makes it fail while waiting to make third call
                var callSettings = CallSettings.FromCallTiming(CallTiming.FromRetry(retrySettings));
                var request      = new SimpleRequest {
                    Name = "irrelevant"
                };
                await Call(async, serverStreaming, scheduler, server, request, callSettings);
            });
            await Assert.ThrowsAsync <RpcException>(() => task);

            var firstCall  = time0;
            var secondCall = firstCall + callDuration + TimeSpan.FromTicks(1000);

            server.AssertCallTimes(firstCall, secondCall);

            // We fail immediately when we work out that we would time out before we make the third
            // call - so this is before the actual total timeout.
            Assert.Equal((secondCall + callDuration).Ticks, scheduler.Clock.GetCurrentDateTimeUtc().Ticks);
        }
        /// <summary>
        /// Creates a service context that binds the service, callsettings and the client.
        /// </summary>
        /// <param name="config">The configuration.</param>
        /// <returns>The service context.</returns>
        private GoogleAdsServiceContext CreateServiceContext(GoogleAdsConfig config)
        {
            GoogleAdsServiceContext serviceContext = new GoogleAdsServiceContext();
            CallSettings            callSettings   = CallSettings.FromCallTiming(
                CallTiming.FromRetry(new RetrySettings(
                                         retryBackoff : backoffSettings,
                                         timeoutBackoff : backoffSettings,
                                         totalExpiration : Expiration.FromTimeout(TimeSpan.FromMilliseconds(
                                                                                      config.Timeout)),
                                         retryFilter : retryFilter
                                         )))
                                                     .WithHeader(GoogleAdsConfig.DEVELOPER_TOKEN_KEYNAME, config.DeveloperToken)
                                                     .WithResponseMetadataHandler(delegate(Metadata metadata)
            {
                GoogleAdsResponseMetadata responseMetadata = new GoogleAdsResponseMetadata(metadata);
                serviceContext.OnResponseMetadataReceived(responseMetadata);
            });

            if (!string.IsNullOrEmpty(config.LoginCustomerId))
            {
                callSettings.WithHeader("login-customer-id", config.LoginCustomerId);
            }

            serviceContext.CallSettings = callSettings;
            return(serviceContext);
        }
Ejemplo n.º 6
0
        public async Task ExponentialTimeouts(bool async, bool serverStreaming)
        {
            var callDuration  = TimeSpan.FromTicks(300);
            var failures      = 2;
            var scheduler     = new FakeScheduler();
            var time0         = scheduler.Clock.GetCurrentDateTimeUtc();
            var server        = new Server(failures, callDuration, scheduler);
            var callable      = server.Callable;
            var retrySettings = new RetrySettings(
                retryBackoff: ConstantBackoff,   // 1500 ticks always
                timeoutBackoff: DoublingBackoff, // 1000, then 2000, then 4000
                totalExpiration: Expiration.FromTimeout(TimeSpan.FromTicks(4500)),
                retryFilter: null,
                delayJitter: RetrySettings.NoJitter);

            await scheduler.RunAsync(async() =>
            {
                // Expiration truncates the third timeout. We expect:
                // Call 1: t=0, deadline=1000, completes at 300
                // Call 2: t=1800, deadline=3800 (2000+1800), completes at 2100
                // Call 3, t=3600, deadline=4500 (would be 7600, but overall deadline truncates), completes at 3900 (with success)
                var callSettings = CallSettings.FromCallTiming(CallTiming.FromRetry(retrySettings));
                var request      = new SimpleRequest {
                    Name = "irrelevant"
                };
                await Call(async, serverStreaming, scheduler, server, request, callSettings);
            });

            server.AssertCallTimes(time0, time0 + TimeSpan.FromTicks(1800), time0 + TimeSpan.FromTicks(3600));
            server.AssertDeadlines(time0 + TimeSpan.FromTicks(1000), time0 + TimeSpan.FromTicks(3800), time0 + TimeSpan.FromTicks(4500));
            Assert.Equal(3900L, scheduler.Clock.GetCurrentDateTimeUtc().Ticks);
        }
Ejemplo n.º 7
0
        public void test()
        {
            LanguageServiceSettings settings = new LanguageServiceSettings();

            if (TimeOut > 0)
            {
                int hour = TimeOut / 3600;
                int min  = TimeOut / 60;
                if (TimeOut >= 60)
                {
                    TimeOut = TimeOut % 60;
                }
                TimeSpan ts0 = new TimeSpan(hour, min, TimeOut);
                settings.AnalyzeSentimentSettings = CallSettings.FromCallTiming(CallTiming.FromTimeout(ts0));
            }
            string json       = "{\"type\": \"service_account\",\"project_id\": \"" + Config["project_id"] + "\",\"private_key_id\": \"" + Config["private_key_id"] + "\",\"private_key\": \"" + Config["private_key"] + "\",\"client_email\": \"" + Config["client_email"] + "\",\"client_id\": \"" + Config["client_id"] + "\",\"auth_uri\": \"" + Config["auth_uri"] + "\",\"token_uri\": \"" + Config["token_uri"] + "\",\"auth_provider_x509_cert_url\": \"" + Config["auth_provider_x509_cert_url"] + "\",\"client_x509_cert_url\": \"" + Config["client_x509_cert_url"] + "\"}";
            var    credential = GoogleCredential.FromJson(json).CreateScoped(LanguageServiceClient.DefaultScopes);
            var    channel    = new Grpc.Core.Channel(
                LanguageServiceClient.DefaultEndpoint.ToString(),
                credential.ToChannelCredentials());
            LanguageServiceClient test = LanguageServiceClient.Create(channel, settings);
            var Sentimentresponse      = test.AnalyzeSentiment(new Document()
            {
                Content = "hello",
                Type    = Document.Types.Type.PlainText
            });
        }
Ejemplo n.º 8
0
        public async Task RetryFilter_EventualSuccess(bool async, bool serverStreaming)
        {
            StatusCode failureCode = StatusCode.NotFound;

            StatusCode[] filterCodes  = new[] { StatusCode.NotFound, StatusCode.DeadlineExceeded };
            var          callDuration = TimeSpan.FromTicks(100);
            var          failures     = 1;
            var          scheduler    = new FakeScheduler();
            var          server       = new Server(failures, callDuration, scheduler, failureCode);
            // We're not really interested in the timing in this test.
            var retrySettings = new RetrySettings(
                retryBackoff: ConstantBackoff,
                timeoutBackoff: ConstantBackoff,
                delayJitter: RetrySettings.NoJitter,
                totalExpiration: Expiration.FromTimeout(TimeSpan.FromSeconds(1)),
                retryFilter: RetrySettings.FilterForStatusCodes(filterCodes));

            await scheduler.RunAsync(async() =>
            {
                var callSettings = CallSettings.FromCallTiming(CallTiming.FromRetry(retrySettings));
                var request      = new SimpleRequest {
                    Name = "irrelevant"
                };
                await Call(async, serverStreaming, scheduler, server, request, callSettings);
            });

            Assert.True(server.CallTimes.Count() > 1);
        }
Ejemplo n.º 9
0
        public async Task RetryFilter_EventualFailure(bool async, bool serverStreaming, StatusCode failureCode, StatusCode[] filterCodes)
        {
            var callDuration = TimeSpan.FromTicks(100);
            var failures     = 1;
            var scheduler    = new FakeScheduler();
            var server       = new Server(failures, callDuration, scheduler, failureCode);
            // We're not really interested in the timing in this test.
            var retrySettings = new RetrySettings(
                retryBackoff: ConstantBackoff,
                timeoutBackoff: ConstantBackoff,
                delayJitter: RetrySettings.NoJitter,
                totalExpiration: Expiration.FromTimeout(TimeSpan.FromSeconds(1)),
                retryFilter: RetrySettings.FilterForStatusCodes(filterCodes));

            var task = scheduler.RunAsync(async() =>
            {
                var callSettings = CallSettings.FromCallTiming(CallTiming.FromRetry(retrySettings));
                var request      = new SimpleRequest {
                    Name = "irrelevant"
                };
                await Call(async, serverStreaming, scheduler, server, request, callSettings);
            });
            await Assert.ThrowsAsync <RpcException>(() => task);

            Assert.Equal(1, server.CallTimes.Count());
        }
Ejemplo n.º 10
0
        public async Task RetryCancellation(bool serverStreaming, [CombinatorialValues(1500, 3500)] int delayMs)
        {
            // Note: Cannot test cancellation during wait for response header, due to FakeScheduler shortcomings.
            var async         = true;
            var scheduler     = new FakeScheduler();
            var time0         = scheduler.Clock.GetCurrentDateTimeUtc();
            var server        = new Server(10, TimeSpan.FromSeconds(1), scheduler);
            var retrySettings = new RetrySettings(
                retryBackoff: new BackoffSettings(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), 1.0),
                timeoutBackoff: new BackoffSettings(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), 1.0),
                delayJitter: RetrySettings.NoJitter,
                totalExpiration: Expiration.FromTimeout(TimeSpan.FromSeconds(10)),
                retryFilter: RetrySettings.DefaultFilter);
            var  delay = TimeSpan.FromMilliseconds(delayMs);
            Task task  = scheduler.RunAsync(async() =>
            {
                var cts    = new CancellationTokenSource();
                var unused = Task.Run(async() =>
                {
                    await scheduler.Delay(delay);
                    cts.Cancel();
                });
                var callSettings = CallSettings.FromCallTiming(CallTiming.FromRetry(retrySettings)).WithCancellationToken(cts.Token);
                var request      = new SimpleRequest {
                    Name = "irrelevant"
                };
                await Call(async, serverStreaming, scheduler, server, request, callSettings);
            });
            await Assert.ThrowsAsync <TaskCanceledException>(() => task);

            Assert.Equal(time0 + delay, scheduler.Clock.GetCurrentDateTimeUtc());
        }
Ejemplo n.º 11
0
        public async Task FirstCallSucceeds(bool async, bool serverStreaming)
        {
            var name          = "name"; // Copied from request to response
            var scheduler     = new FakeScheduler();
            var time0         = scheduler.Clock.GetCurrentDateTimeUtc();
            var server        = new Server(0, TimeSpan.FromTicks(300), scheduler);
            var retrySettings = new RetrySettings(
                retryBackoff: DoublingBackoff,
                timeoutBackoff: ConstantBackoff,
                totalExpiration: Expiration.FromTimeout(TimeSpan.FromSeconds(1)),
                retryFilter: null,
                delayJitter: RetrySettings.NoJitter);

            await scheduler.RunAsync(async() =>
            {
                var callSettings = CallSettings.FromCallTiming(CallTiming.FromRetry(retrySettings));
                var request      = new SimpleRequest {
                    Name = name
                };
                var result = await Call(async, serverStreaming, scheduler, server, request, callSettings);
                Assert.Equal(name, result.Name);
            });

            server.AssertCallTimes(time0);
            // Time of last action was when the call returned
            Assert.Equal(300, scheduler.Clock.GetCurrentDateTimeUtc().Ticks);
        }
Ejemplo n.º 12
0
        // [START monitoring_uptime_check_create]
        public static object CreateUptimeCheck(string projectId, string hostName,
                                               string displayName)
        {
            // Define a new config.
            var config = new UptimeCheckConfig()
            {
                DisplayName       = displayName,
                MonitoredResource = new MonitoredResource()
                {
                    Type   = "uptime_url",
                    Labels = { { "host", hostName } }
                },
                HttpCheck = new UptimeCheckConfig.Types.HttpCheck()
                {
                    Path = "/",
                    Port = 80,
                },
                Timeout = TimeSpan.FromSeconds(10).ToDuration(),
                Period  = TimeSpan.FromMinutes(5).ToDuration()
            };
            // Create a client.
            var    client      = UptimeCheckServiceClient.Create();
            string projectName = new ProjectName(projectId).ToString();
            // Create the config.
            var newConfig = client.CreateUptimeCheckConfig(projectName, config,
                                                           CallSettings.FromCallTiming(CallTiming.FromTimeout(TimeSpan.FromMinutes(2))));

            Console.WriteLine(newConfig.Name);
            return(0);
        }
Ejemplo n.º 13
0
        public void FromCallTiming()
        {
            Assert.Null(CallSettings.FromCallTiming(null));
            var timing   = CallTiming.FromExpiration(Expiration.None);
            var settings = CallSettings.FromCallTiming(timing);

            Assert.Same(timing, settings.Timing);
        }
        public void SucceedWithExpiration()
        {
            var apiCall = ApiServerStreamingCall.Create <int, int>(
                (request, callOptions) => null,
                CallSettings.FromCallTiming(CallTiming.FromExpiration(Expiration.FromTimeout(TimeSpan.FromSeconds(100)))),
                new FakeClock());

            Assert.Null(apiCall.Call(0, null));
        }
Ejemplo n.º 15
0
        public void ToCallOptions_CallTimingNull()
        {
            var          mockClock    = new Mock <IClock>();
            CallSettings callSettings = CallSettings.FromCallTiming(null);
            var          options      = callSettings.ToCallOptions(mockClock.Object);

            Assert.Null(options.Deadline);
            mockClock.Verify(c => c.GetCurrentDateTimeUtc(), Times.Never);
        }
Ejemplo n.º 16
0
        public void SucceedWithExpiration()
        {
            var apiCall = ApiBidirectionalStreamingCall.Create <int, int>(
                callOptions => null,
                CallSettings.FromCallTiming(CallTiming.FromExpiration(Expiration.FromTimeout(TimeSpan.FromSeconds(100)))),
                new BidirectionalStreamingSettings(100),
                new FakeClock());

            Assert.Null(apiCall.Call(null));
        }
Ejemplo n.º 17
0
        public void ToCallOptions_CallTimingExpirationTimeout()
        {
            var          clock        = new FakeClock();
            var          timeout      = TimeSpan.FromSeconds(1);
            CallSettings callSettings = CallSettings.FromCallTiming(CallTiming.FromExpiration(Expiration.FromTimeout(timeout)));
            var          options      = callSettings.ToCallOptions(clock);

            // Value should be exact, as we control time precisely.
            Assert.Equal(options.Deadline.Value, clock.GetCurrentDateTimeUtc() + timeout);
        }
Ejemplo n.º 18
0
        public void ToCallOptions_CallTimingExpirationDeadline()
        {
            var          deadline     = new DateTime(2015, 6, 19, 5, 2, 3, DateTimeKind.Utc);
            var          mockClock    = new Mock <IClock>();
            CallSettings callSettings = CallSettings.FromCallTiming(CallTiming.FromExpiration(Expiration.FromDeadline(deadline)));
            var          options      = callSettings.ToCallOptions(mockClock.Object);

            // Value should be exact, as we control time precisely.
            Assert.Equal(options.Deadline.Value, deadline);
            mockClock.Verify(c => c.GetCurrentDateTimeUtc(), Times.Never);
        }
Ejemplo n.º 19
0
 public StackDriverLogger(string projectId)
 {
     _projectId   = projectId;
     _retryAWhile = CallSettings.FromCallTiming(CallTiming.FromRetry(new RetrySettings(
                                                                         new BackoffSettings(TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(12), 2.0),
                                                                         new BackoffSettings(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(120)),
                                                                         Google.Api.Gax.Expiration.FromTimeout(TimeSpan.FromSeconds(180)),
                                                                         (Grpc.Core.RpcException e) =>
                                                                         new[] { Grpc.Core.StatusCode.Internal, Grpc.Core.StatusCode.DeadlineExceeded }
                                                                         .Contains(e.Status.StatusCode)
                                                                         )));
 }
        public void FailWithRetry()
        {
            var apiCall = ApiServerStreamingCall.Create <int, int>(
                (request, callOptions) => null,
                CallSettings.FromCallTiming(CallTiming.FromRetry(new RetrySettings(
                                                                     new BackoffSettings(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(100), 2.0),
                                                                     new BackoffSettings(TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(100), 2.0),
                                                                     Expiration.FromTimeout(TimeSpan.FromSeconds(100))))),
                new FakeClock());

            Assert.Throws <InvalidOperationException>(() => apiCall.Call(0, null));
        }
        /// <inheritdoc />
        public async Task <SpannerClient> CreateClientAsync(ServiceEndpoint endpoint, ITokenAccess credential, IDictionary additionalOptions)
        {
            ChannelCredentials channelCredentials;
            var allowImmediateTimeout = false;

            if (additionalOptions.Contains(nameof(SpannerSettings.AllowImmediateTimeouts)))
            {
                allowImmediateTimeout = Convert.ToBoolean(additionalOptions[nameof(SpannerSettings.AllowImmediateTimeouts)]);
            }

            if (credential == null)
            {
                channelCredentials = await CreateDefaultChannelCredentialsAsync().ConfigureAwait(false);
            }
            else
            {
                channelCredentials = credential.ToChannelCredentials();
            }

            var channel = new Channel(
                endpoint.Host,
                endpoint.Port,
                channelCredentials);

            Logger.LogPerformanceCounterFn("SpannerClient.RawCreateCount", x => x + 1);

            //Pull the timeout from spanner options.
            //The option must be set before OpenAsync is called.
            var idempotentCallSettings = CallSettings.FromCallTiming(
                CallTiming.FromRetry(
                    new RetrySettings(
                        SpannerSettings.GetDefaultRetryBackoff(),
                        SpannerSettings.GetDefaultTimeoutBackoff(),
                        SpannerSettings.ConvertTimeoutToExpiration(SpannerOptions.Instance.Timeout, allowImmediateTimeout),
                        SpannerSettings.IdempotentRetryFilter
                        )));

            return(SpannerClient.Create(
                       channel, new SpannerSettings
            {
                CreateSessionSettings = idempotentCallSettings,
                GetSessionSettings = idempotentCallSettings,
                DeleteSessionSettings = idempotentCallSettings,
                ExecuteSqlSettings = idempotentCallSettings,
                ReadSettings = idempotentCallSettings,
                BeginTransactionSettings = idempotentCallSettings,
                CommitSettings = idempotentCallSettings,
                RollbackSettings = idempotentCallSettings,
                AllowImmediateTimeouts = allowImmediateTimeout
            }));
        }
        /// <summary>
        /// Makes one call to PubSub.Pull to pull some books from the subscription.
        /// </summary>
        // [START pullonce]
        private void PullOnce(Action <long> callback, CancellationToken cancellationToken)
        {
            _logger.LogVerbose($"Pulling messages from {_subscriptionName}...");
            // Pull some messages from the subscription.

            var response = _sub.Pull(_subscriptionName, false, 3,
                                     CallSettings.FromCallTiming(
                                         CallTiming.FromExpiration(
                                             Expiration.FromTimeout(
                                                 TimeSpan.FromSeconds(90)))));

            if (response.ReceivedMessages == null)
            {
                // HTTP Request expired because the queue was empty.  Ok.
                _logger.LogVerbose("Pulled no messages.");
                return;
            }
            _logger.LogVerbose($"Pulled {response.ReceivedMessages.Count} messages.");
            if (response.ReceivedMessages.Count == 0)
            {
                return;
            }
            foreach (var message in response.ReceivedMessages)
            {
                try
                {
                    // Unpack the message.
                    byte[] json     = message.Message.Data.ToByteArray();
                    var    qmessage = JsonConvert.DeserializeObject <QueueMessage>(
                        Encoding.UTF8.GetString(json));
                    // Invoke ProcessBook().
                    callback(qmessage.BookId);
                }
                catch (Exception e)
                {
                    _logger.LogError("Error processing book.", e);
                }
            }
            // Acknowledge the message so we don't see it again.
            var ackIds = new string[response.ReceivedMessages.Count];

            for (int i = 0; i < response.ReceivedMessages.Count; ++i)
            {
                ackIds[i] = response.ReceivedMessages[i].AckId;
            }
            _sub.Acknowledge(_subscriptionName, ackIds);
        }
Ejemplo n.º 23
0
        private FirestoreDb(string projectId, string databaseId, FirestoreClient client, Action <string> warningLogger)
        {
            ProjectId  = GaxPreconditions.CheckNotNull(projectId, nameof(projectId));
            DatabaseId = GaxPreconditions.CheckNotNull(databaseId, nameof(databaseId));
            Client     = GaxPreconditions.CheckNotNull(client, nameof(client));
            // TODO: Investigate using DatabaseName and DocumentPathName.
            RootPath      = $"projects/{ProjectId}/databases/{DatabaseId}";
            DocumentsPath = $"{RootPath}/documents";
            WarningLogger = warningLogger;

            // TODO: Validate these settings, and potentially make them configurable
            _batchGetCallSettings = CallSettings.FromCallTiming(CallTiming.FromRetry(new RetrySettings(
                                                                                         retryBackoff: new BackoffSettings(TimeSpan.FromMilliseconds(500), TimeSpan.FromSeconds(5), 2.0),
                                                                                         timeoutBackoff: new BackoffSettings(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(3), 2.0),
                                                                                         Expiration.FromTimeout(TimeSpan.FromMinutes(10)),
                                                                                         RetrySettings.FilterForStatusCodes(StatusCode.Unavailable))));
        }
        public FirebaseDocumentListener(FirestoreDb db)
        {
            // Create client
            FirestoreDb     = db;
            FirestoreClient = db.Client; //FirestoreClient.Create();
            ProjectId       = db.ProjectId;
            DatabaseId      = db.DatabaseId;

            //Setup no expiration for the listen
            ListenSettings = CallSettings.FromCallTiming(CallTiming.FromExpiration(Expiration.None));

            //Start our handler for writing requests to GCP
            RequestHanderTask = StartRequestHandlerTask();

            //Initialize a cancelation source so we can cancel tasks we create
            CancellationTokenSource = new CancellationTokenSource();
            CancellationToken       = CancellationTokenSource.Token;
        }
Ejemplo n.º 25
0
        public void Overrides()
        {
            string            projectId         = _fixture.ProjectId;
            string            topicId           = _fixture.CreateTopicId();
            DateTime          deadline          = DateTime.MaxValue;
            CancellationToken cancellationToken = new CancellationTokenSource().Token;

            // Sample: Overrides
            // Create a default PublisherServiceApiSettings, with customizations for CreateTopic RPCs:
            // * A custom "ClientVersion" header.
            // * A custom 5-second timeout Timing.
            // * No cancellation token.
            PublisherServiceApiSettings publisherSettings = new PublisherServiceApiSettings();

            publisherSettings.CreateTopicSettings = publisherSettings.CreateTopicSettings
                                                    .WithCancellationToken(CancellationToken.None)
                                                    .WithCallTiming(CallTiming.FromTimeout(TimeSpan.FromSeconds(5)))
                                                    .WithHeader("ClientVersion", "1.0.0");

            // Override the above Timing and CancellationToken in the client-wide CallSettings;
            // the Headers are not overridden.
            publisherSettings.CallSettings = CallSettings
                                             .FromCallTiming(CallTiming.FromDeadline(deadline))
                                             .WithCancellationToken(CancellationToken.None);

            // Create the client with the configured publisherSettings
            PublisherServiceApiClient client = PublisherServiceApiClient.Create(settings: publisherSettings);

            // Create a topic name from the projectId and topicId.
            TopicName topicName = new TopicName(projectId, topicId);

            // Call CreateTopic(). Override only the CancellationToken, using a per-RPC-method CallSettings.
            // The CallSettings used during this RPC invocation is:
            // * A custom "ClientVersion" header.
            // * A Timing deadline of 'deadline' (*not* the overridden 5-second timeout).
            // * The CancellationToken 'cancellationToken' (*not* CancellationToken.None).
            Topic topic = client.CreateTopic(topicName, CallSettings.FromCancellationToken(cancellationToken));
            // End sample
        }
        private async Task RunBulkMessaging(
            int messageCount, int minMessageSize, int maxMessageSize, int maxMessagesInFlight, int initialNackCount,
            TimeSpan?timeouts = null, int?cancelAfterRecvCount = null)
        {
            // Force messages to be at least 4 bytes long, so an int ID can be used.
            minMessageSize = Math.Max(4, minMessageSize);
            var topicId        = _fixture.CreateTopicId();
            var subscriptionId = _fixture.CreateSubscriptionId();

            Console.WriteLine("BulkMessaging test");
            Console.WriteLine($"{messageCount} messages; of size [{minMessageSize}, {maxMessageSize}]; " +
                              $"max in-flight: {maxMessagesInFlight}, initialNacks: {initialNackCount}, cancelAfterRecvCount: {cancelAfterRecvCount}");

            // Create topic
            var topicName = new TopicName(_fixture.ProjectId, topicId);
            var publisher = await PublisherClient.CreateAsync().ConfigureAwait(false);

            await publisher.CreateTopicAsync(topicName).ConfigureAwait(false);

            // Subscribe to the topic
            var subscriber = await SubscriberClient.CreateAsync().ConfigureAwait(false);

            var subscriptionName = new SubscriptionName(_fixture.ProjectId, subscriptionId);
            await subscriber.CreateSubscriptionAsync(subscriptionName, topicName, null, 60).ConfigureAwait(false);

            // Create SimplePublisher and SimpleSubscriber
            var simplePublisher = await SimplePublisher.CreateAsync(topicName, clientCreationSettings : timeouts == null?null :
                                                                    new SimplePublisher.ClientCreationSettings(
                                                                        publisherSettings: new PublisherSettings
            {
                PublishSettings = CallSettings.FromCallTiming(CallTiming.FromRetry(new RetrySettings(
                                                                                       retryBackoff: PublisherSettings.GetMessagingRetryBackoff(),
                                                                                       timeoutBackoff: new BackoffSettings(timeouts.Value, timeouts.Value, 1.0),
                                                                                       totalExpiration: Expiration.FromTimeout(timeouts.Value),
                                                                                       retryFilter: PublisherSettings.NonIdempotentRetryFilter
                                                                                       )))
            }
                                                                        )).ConfigureAwait(false);

            var simpleSubscriber = await SimpleSubscriber.CreateAsync(subscriptionName,
                                                                      settings : new SimpleSubscriber.Settings
            {
                StreamAckDeadline   = timeouts,
                FlowControlSettings = new FlowControlSettings(maxMessagesInFlight, null)
            }).ConfigureAwait(false);

            Console.WriteLine("Topic, Subscription, SimplePublisher and SimpleSubscriber all created");

            // Subscribe
            object recvLock  = new object();
            int    recvCount = 0;  // Count of received messages
            int    dupCount  = 0;  // Count of duplicate messages
            long   recvSum   = 0L; // Sum of bytes of received messages
            var    recvedIds = new ConcurrentDictionary <int, bool>();
            var    nackedIds = new HashSet <int>();
            Task   subTask   = simpleSubscriber.StartAsync((msg, ct) =>
            {
                int id = BitConverter.ToInt32(msg.Data.ToArray(), 0);
                lock (nackedIds)
                {
                    if (nackedIds.Count < initialNackCount)
                    {
                        if (nackedIds.Add(id))
                        {
                            // This ID not already nacked
                            Interlocked.Increment(ref recvCount);
                            return(Task.FromResult(SimpleSubscriber.Reply.Nack));
                        }
                    }
                }
                bool wasAdded = recvedIds.TryAdd(id, false);
                if (wasAdded)
                {
                    var localRecvCount = Interlocked.Increment(ref recvCount);
                    Interlocked.Add(ref recvSum, msg.Data.Sum(x => (long)x));
                    if (localRecvCount == cancelAfterRecvCount || localRecvCount >= messageCount + initialNackCount)
                    {
                        // Test finished, so stop subscriber
                        Task unused = simpleSubscriber.StopAsync(TimeSpan.FromSeconds(15));
                    }
                }
                else
                {
                    Interlocked.Add(ref dupCount, 1);
                }
                // ACK all messages
                return(Task.FromResult(SimpleSubscriber.Reply.Ack));
            });

            // Publish
            var  rnd        = new Random(1234);
            var  activePubs = new HashSet <Task>();
            int  sentCount  = 0;
            long sentSum    = 0L; // Sum of bytes of sent messages

            // Watchdog to report progress and fail test on deadlock
            CancellationTokenSource watchdogCts = new CancellationTokenSource();

            Task.Run(async() =>
            {
                int prevSentCount   = -1;
                int prevRecvCount   = -1;
                int noProgressCount = 0;
                while (!watchdogCts.IsCancellationRequested)
                {
                    await Task.Delay(TimeSpan.FromSeconds(1), watchdogCts.Token).ConfigureAwait(false);
                    var localSentCount = Interlocked.Add(ref sentCount, 0);
                    var localRecvCount = Interlocked.Add(ref recvCount, 0);
                    var localDupCount  = Interlocked.Add(ref dupCount, 0);
                    if (prevSentCount == localSentCount && prevRecvCount == localRecvCount)
                    {
                        if (noProgressCount > 100)
                        {
                            // Deadlock, shutdown subscriber, and cancel
                            Console.WriteLine("Deadlock detected. Cancelling test");
                            simpleSubscriber.StopAsync(new CancellationToken(true));
                            watchdogCts.Cancel();
                            break;
                        }
                        noProgressCount += 1;
                    }
                    else
                    {
                        noProgressCount = 0;
                    }
                    prevSentCount = localSentCount;
                    prevRecvCount = localRecvCount;
                    Console.WriteLine($"Sent: {localSentCount} (in-flight: {activePubs.Locked(() => activePubs.Count)}); Recv: {localRecvCount} (dups: {localDupCount})");
                }
            });

            for (int i = 0; i < messageCount; i++)
            {
                if (watchdogCts.IsCancellationRequested)
                {
                    Assert.True(false, "Test cancelled by watchdog");
                }
                if (subTask.IsCompleted)
                {
                    break;
                }
                var msgSize = rnd.Next(minMessageSize, maxMessageSize + 1);
                var msg     = new byte[msgSize];
                rnd.NextBytes(msg);
                // Insert an int ID into message
                Array.Copy(BitConverter.GetBytes(i), msg, 4);
                sentSum += msg.Sum(x => (long)x);
                // Send message, and record Task
                var pubTask = simplePublisher.PublishAsync(msg);
                Interlocked.Increment(ref sentCount);
                activePubs.Locked(() => activePubs.Add(pubTask));
                // Remove Task from active when the message has been sent to server
                pubTask.ContinueWith(t => activePubs.Locked(() => activePubs.Remove(pubTask)));
                // If too many messages are currently in flight, wait a bit
                while (activePubs.Locked(() => activePubs.Count) >= maxMessagesInFlight)
                {
                    await Task.Delay(TimeSpan.FromMilliseconds(1)).ConfigureAwait(false);
                }
            }
            Console.WriteLine("Publishing complete");
            // Wait for all messages to be sent to server
            await Task.WhenAll(activePubs.Locked(() => activePubs.ToArray())).ConfigureAwait(false);

            Console.WriteLine("Publishing completed sending to server");

            // Wait for subscriber to finish shutdown
            await subTask.ConfigureAwait(false);

            watchdogCts.Cancel();
            Console.WriteLine("Subscriber finished shutdown");
            Console.WriteLine($"Sent: {sentCount}; Recv: {recvCount}");

            if (cancelAfterRecvCount is int cancelAfter)
            {
                Assert.True(recvCount >= cancelAfter && recvCount <= cancelAfter + maxMessagesInFlight, $"Incorrect recvCount: {recvCount}");
            }
            else
            {
                // Check that all messages are correctly received.
                Assert.Equal(messageCount + initialNackCount, recvCount);
                // This isn't foolproof (we can get to the right sum with wrong values) but it's a pretty strong indicator.
                Assert.Equal(sentSum, recvSum);
            }
        }