Ejemplo n.º 1
0
 /// <summary>
 /// <para>Sets up a module that enriches all requests with two auxiliary headers:</para>
 /// <list type="bullet">
 ///     <item><description><paramref name="priorityHeader"/> with the value of request's <see cref="RequestParameters.Priority"/></description></item>
 ///     <item><description><paramref name="identityHeader"/> with the value of configuration's <see cref="IClusterClientConfiguration.ClientApplicationName"/></description></item>
 /// </list>
 /// </summary>
 public static void SetupAuxiliaryHeaders(
     this IClusterClientConfiguration configuration,
     string priorityHeader = HeaderNames.RequestPriority,
     string identityHeader = HeaderNames.ApplicationIdentity)
 {
     configuration.AddRequestModule(new AuxiliaryHeadersModule(priorityHeader, identityHeader));
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Inject latency to the every strategy IRequestSender.SendToReplicaAsync call with default latency performer
 /// </summary>
 /// <example>
 /// <code>
 ///   ---► + injected latency ---► replica1 ---► + injected latency ---> replica2 ...
 ///                                                          ◄---------------------|
 ///
 /// </code>
 /// </example>
 /// <param name="configuration">IClusterClientConfiguration instance</param>
 /// <param name="latencyProvider">Func returning latency to inject</param>
 /// <param name="rateProvider">Func returning injection probability (rate)</param>
 public static void InjectLatencyOnEveryNetworkCall(
     this IClusterClientConfiguration configuration,
     Func <TimeSpan> latencyProvider,
     Func <double> rateProvider)
 {
     configuration.DefaultRequestStrategy = new LatencyStrategy(new LatencyPerformer(), new RateManager(), latencyProvider, rateProvider, configuration.DefaultRequestStrategy);
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Inject latency to the every request retry with default latency performer
 /// </summary>
 /// <example>
 /// <code>
 ///   ------► + injected latency ---► replica(1..n)
 ///     ↑__________retry (1..n)__________________|
 /// </code>
 /// </example>
 /// <param name="configuration">IClusterClientConfiguration instance</param>
 /// <param name="latencyProvider">Func returning latency to inject</param>
 /// <param name="rateProvider">Func returning injection probability (rate)</param>
 public static void InjectLatencyOnEveryRetry(
     this IClusterClientConfiguration configuration,
     Func <TimeSpan> latencyProvider,
     Func <double> rateProvider)
 {
     configuration.AddRequestModule(new LatencyModule(new LatencyPerformer(), new RateManager(), latencyProvider, rateProvider), RequestModule.RequestRetry, ModulePosition.After);
 }
Ejemplo n.º 4
0
        /// <summary>
        /// <para>Sets up given <paramref name="configuration"/> to send requests to an API behind given external <paramref name="url"/>.</para>
        /// <para>Does not set up a transport.</para>
        /// </summary>
        public static void SetupExternalUrl([NotNull] this IClusterClientConfiguration configuration, [NotNull] Uri url)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (url == null)
            {
                throw new ArgumentNullException(nameof(url));
            }

            if (!url.IsAbsoluteUri)
            {
                throw new ArgumentException($"External url must be an absolute URI. Instead, got this: '{url}'.");
            }

            configuration.ClusterProvider = new FixedClusterProvider(url);

            configuration.MaxReplicasUsedPerRequest = 3;

            configuration.RepeatReplicas(configuration.MaxReplicasUsedPerRequest);

            configuration.ReplicaOrdering = new AsIsReplicaOrdering();

            configuration.SetupReplicaBudgeting(minimumRequests: 10);

            configuration.DefaultRequestStrategy = Strategy.Sequential1;

            configuration.DeduplicateRequestUrl = true;

            configuration.TargetServiceName = url.AbsoluteUri;
        }
        public void TestSetup()
        {
            replica           = new Uri("http://replica/");
            relativeRequest   = Request.Get("foo/bar");
            absoluteRequest   = Request.Get("http://replica/foo/bar");
            response          = new Response(ResponseCode.Ok);
            timeout           = 5.Seconds();
            connectionTimeout = null;

            replicaOrdering = Substitute.For <IReplicaOrdering>();

            configuration = Substitute.For <IClusterClientConfiguration>();
            configuration.ResponseCriteria.Returns(new List <IResponseCriterion> {
                Substitute.For <IResponseCriterion>()
            });
            configuration.Logging.Returns(
                new LoggingOptions
            {
                LogReplicaRequests = true,
                LogReplicaResults  = true
            });
            configuration.ReplicaOrdering.Returns(replicaOrdering);
            configuration.Log.Returns(log = Substitute.For <ILog>());

            log.IsEnabledFor(default).ReturnsForAnyArgs(true);
Ejemplo n.º 6
0
        /// <summary>
        /// Initializes configuration's <see cref="IClusterClientConfiguration.ReplicaOrdering"/> with a <see cref="WeighedReplicaOrdering"/> built with a given delegate acting on a <see cref="IWeighedReplicaOrderingBuilder"/> instance.
        /// </summary>
        public static void SetupWeighedReplicaOrdering(this IClusterClientConfiguration configuration, Action <IWeighedReplicaOrderingBuilder> build)
        {
            var builder = new WeighedReplicaOrderingBuilder(configuration.TargetEnvironment, configuration.TargetServiceName, configuration.Log);

            build(builder);
            configuration.ReplicaOrdering = builder.Build();
        }
        public void SetUp()
        {
            replica         = new Uri("http://replica/");
            relativeRequest = Request.Get("foo/bar");
            absoluteRequest = Request.Get("http://replica/foo/bar");
            response        = new Response(ResponseCode.Ok);
            timeout         = 5.Seconds();

            log = Substitute.For <ILog>();
            log
            .When(l => l.Log(Arg.Any <LogEvent>()))
            .Do(info => new ConsoleLog().Log(info.Arg <LogEvent>()));

            configuration = Substitute.For <IClusterClientConfiguration>();
            configuration.ResponseCriteria.Returns(new List <IResponseCriterion> {
                Substitute.For <IResponseCriterion>()
            });
            configuration.LogReplicaRequests.Returns(true);
            configuration.LogReplicaResults.Returns(true);
            configuration.ReplicaOrdering.Returns(Substitute.For <IReplicaOrdering>());
            configuration.Log.Returns(log);

            storageProvider = Substitute.For <IReplicaStorageProvider>();

            responseClassifier = Substitute.For <IResponseClassifier>();
            responseClassifier.Decide(Arg.Any <Response>(), Arg.Any <IList <IResponseCriterion> >()).Returns(ResponseVerdict.Accept);

            requestConverter = Substitute.For <IRequestConverter>();
            requestConverter.TryConvertToAbsolute(relativeRequest, replica).Returns(_ => absoluteRequest);

            transport = Substitute.For <ITransport>();
            transport.SendAsync(Arg.Any <Request>(), Arg.Any <TimeSpan>(), Arg.Any <CancellationToken>()).Returns(_ => response);

            sender = new RequestSender(configuration, storageProvider, responseClassifier, requestConverter, transport);
        }
Ejemplo n.º 8
0
        public void SetUp()
        {
            configuration       = Substitute.For <IClusterClientConfiguration>();
            underlyingTransport = Substitute.For <ITransport>();
            transport           = new TransportWithAuxiliaryHeaders(underlyingTransport, configuration);

            request = Request.Get("http://foo/bar");
        }
Ejemplo n.º 9
0
 /// <summary>
 /// <para>Adds given <paramref name="module"/> to configuration's <see cref="IClusterClientConfiguration.Modules"/> collection.</para>
 /// <para><paramref name="module"/> will be inserted into request module chain once near <paramref name="relatedModule"/>.</para>
 /// </summary>
 /// <param name="relatedModule">A module near which <paramref name="module"/> will be inserted.</param>
 /// <param name="module">A module to insert into request pipeline.</param>
 /// <param name="configuration">A configuration instance.</param>
 /// <param name="position">A relative position of <paramref name="module"/> from <paramref name="relatedModule"/>. This parameter is optional and has default value <see cref="ModulePosition.Before"/>.</param>
 public static void AddRequestModule(
     this IClusterClientConfiguration configuration,
     IRequestModule module,
     RequestModule relatedModule = RequestModule.Logging,
     ModulePosition position     = ModulePosition.Before)
 {
     configuration.AddRequestModule(module, RequestModulesMapping.GetModuleType(relatedModule), position);
 }
 /// <summary>
 /// Sets up a replica budgeting mechanism with given parameters.
 /// </summary>
 /// <param name="configuration">A configuration to be modified.</param>
 /// <param name="storageKey">See <see cref="ReplicaBudgetingOptions.StorageKey"/>.</param>
 /// <param name="minutesToTrack">See <see cref="ReplicaBudgetingOptions.MinutesToTrack"/>.</param>
 /// <param name="minimumRequests">See <see cref="ReplicaBudgetingOptions.MinimumRequests"/>.</param>
 /// <param name="criticalRatio">See <see cref="ReplicaBudgetingOptions.CriticalRatio"/>.</param>
 public static void SetupReplicaBudgeting(
     this IClusterClientConfiguration configuration,
     string storageKey,
     int minutesToTrack   = ClusterClientDefaults.ReplicaBudgetingMinutesToTrack,
     int minimumRequests  = ClusterClientDefaults.ReplicaBudgetingMinimumRequests,
     double criticalRatio = ClusterClientDefaults.ReplicaBudgetingCriticalRatio)
 {
     configuration.ReplicaBudgeting = new ReplicaBudgetingOptions(storageKey, minutesToTrack, minimumRequests, criticalRatio);
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Modifies configuration's <see cref="IClusterClientConfiguration.ClusterProvider"/> to repeat all of its replicas <paramref name="repeatCount"/> times.
        /// </summary>
        public static void RepeatReplicas(this IClusterClientConfiguration configuration, int repeatCount)
        {
            if (configuration.ClusterProvider == null)
            {
                return;
            }

            configuration.ClusterProvider = new RepeatingClusterProvider(configuration.ClusterProvider, repeatCount);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Adds a <see cref="DistributedContextModule"/> to request modules pipeline and wraps transport with <see cref="DistributedContextTransport"/>.
        /// </summary>
        public static void SetupDistributedContext([NotNull] this IClusterClientConfiguration configuration)
        {
            configuration.AddRequestModule(new DistributedContextModule(), RequestModule.AuxiliaryHeaders);

            if (!(configuration.Transport is DistributedContextTransport))
            {
                configuration.Transport = new DistributedContextTransport(configuration.Transport);
            }
        }
Ejemplo n.º 13
0
        internal static void ApplyReplicaTransform(this IClusterClientConfiguration configuration)
        {
            if (configuration.ReplicaTransform == null)
            {
                return;
            }

            configuration.ClusterProvider = new TransformingClusterProvider(configuration.ClusterProvider, configuration.ReplicaTransform);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// <para>Sets up a decorator over current <see cref="ITransport"/> that enriches all requests with given <paramref name="header"/> containing request timeout in seconds in the following format: <c>s.mmm</c>.</para>
        /// </summary>
        public static void SetupRequestTimeoutHeader(this IClusterClientConfiguration configuration, string header = HeaderNames.RequestTimeout)
        {
            if (configuration.Transport == null)
            {
                return;
            }

            configuration.Transport = new TimeoutHeaderTransport(configuration.Transport, header);
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Sets up an <see cref="IClusterProvider"/> that will fetch replicas of <paramref name="application"/> in <paramref name="environment"/> from ServiceDiscovery with given <paramref name="serviceLocator"/>
 /// </summary>
 public static void SetupServiceDiscoveryTopology(
     [NotNull] this IClusterClientConfiguration self,
     [NotNull] IServiceLocator serviceLocator,
     [NotNull] string environment,
     [NotNull] string application)
 {
     self.ClusterProvider = new ServiceDiscoveryClusterProvider(serviceLocator, environment, application, self.Log);
     self.TargetEnvironment = environment;
     self.TargetServiceName = application;
 }
        /// <summary>
        /// Sets up a replica budgeting mechanism with given parameters using <see cref="IClusterClientConfiguration.TargetServiceName"/> and <see cref="IClusterClientConfiguration.TargetEnvironment"/> as a storage key.
        /// </summary>
        /// <param name="configuration">A configuration to be modified.</param>
        /// <param name="minutesToTrack">See <see cref="ReplicaBudgetingOptions.MinutesToTrack"/>.</param>
        /// <param name="minimumRequests">See <see cref="ReplicaBudgetingOptions.MinimumRequests"/>.</param>
        /// <param name="criticalRatio">See <see cref="ReplicaBudgetingOptions.CriticalRatio"/>.</param>
        public static void SetupReplicaBudgeting(
            this IClusterClientConfiguration configuration,
            int minutesToTrack   = ClusterClientDefaults.ReplicaBudgetingMinutesToTrack,
            int minimumRequests  = ClusterClientDefaults.ReplicaBudgetingMinimumRequests,
            double criticalRatio = ClusterClientDefaults.ReplicaBudgetingCriticalRatio)
        {
            var storageKey = GenerateStorageKey(configuration.TargetEnvironment, configuration.TargetServiceName);

            SetupReplicaBudgeting(configuration, storageKey, minutesToTrack, minimumRequests, criticalRatio);
        }
 /// <summary>
 /// Sets up an adaptive client throttling mechanism with given parameters.
 /// </summary>
 /// <param name="configuration">A configuration to be modified.</param>
 /// <param name="storageKey">See <see cref="AdaptiveThrottlingOptions.StorageKey"/>.</param>
 /// <param name="minutesToTrack">See <see cref="AdaptiveThrottlingOptions.MinutesToTrack"/>.</param>
 /// <param name="minimumRequests">See <see cref="AdaptiveThrottlingOptions.MinimumRequests"/>.</param>
 /// <param name="criticalRatio">See <see cref="AdaptiveThrottlingOptions.CriticalRatio"/>.</param>
 /// <param name="maximumRejectProbability">See <see cref="AdaptiveThrottlingOptions.MaximumRejectProbability"/>.</param>
 public static void SetupAdaptiveThrottling(
     this IClusterClientConfiguration configuration,
     string storageKey,
     int minutesToTrack              = ClusterClientDefaults.AdaptiveThrottlingMinutesToTrack,
     int minimumRequests             = ClusterClientDefaults.AdaptiveThrottlingMinimumRequests,
     double criticalRatio            = ClusterClientDefaults.AdaptiveThrottlingCriticalRatio,
     double maximumRejectProbability = ClusterClientDefaults.AdaptiveThrottlingRejectProbabilityCap)
 {
     configuration.AdaptiveThrottling = new AdaptiveThrottlingOptions(storageKey, minutesToTrack, minimumRequests, criticalRatio, maximumRejectProbability);
 }
        /// <summary>
        /// Sets up a replica budgeting mechanism with given parameters.
        /// </summary>
        /// <param name="configuration">A configuration to be modified.</param>
        /// <param name="storageKey">See <see cref="ReplicaBudgetingOptions.StorageKey"/>.</param>
        /// <param name="minutesToTrack">See <see cref="ReplicaBudgetingOptions.MinutesToTrack"/>.</param>
        /// <param name="minimumRequests">See <see cref="ReplicaBudgetingOptions.MinimumRequests"/>.</param>
        /// <param name="criticalRatio">See <see cref="ReplicaBudgetingOptions.CriticalRatio"/>.</param>
        public static void SetupReplicaBudgeting(
            this IClusterClientConfiguration configuration,
            string storageKey,
            int minutesToTrack   = ClusterClientDefaults.ReplicaBudgetingMinutesToTrack,
            int minimumRequests  = ClusterClientDefaults.ReplicaBudgetingMinimumRequests,
            double criticalRatio = ClusterClientDefaults.ReplicaBudgetingCriticalRatio)
        {
            var options = new ReplicaBudgetingOptions(storageKey, minutesToTrack, minimumRequests, criticalRatio);

            configuration.AddRequestModule(new ReplicaBudgetingModule(options), RequestModule.RequestExecution);
        }
Ejemplo n.º 19
0
 public RequestSender(
     IClusterClientConfiguration configuration,
     IReplicaStorageProvider storageProvider,
     IResponseClassifier responseClassifier,
     IRequestConverter requestConverter)
 {
     this.configuration      = configuration;
     this.storageProvider    = storageProvider;
     this.responseClassifier = responseClassifier;
     this.requestConverter   = requestConverter;
 }
Ejemplo n.º 20
0
        /// <summary>
        /// Sets up an adaptive client throttling mechanism with given parameters using <see cref="IClusterClientConfiguration.TargetServiceName"/> and <see cref="IClusterClientConfiguration.TargetEnvironment"/> as a storage key.
        /// </summary>
        /// <param name="configuration">A configuration to be modified.</param>
        /// <param name="minutesToTrack">See <see cref="AdaptiveThrottlingOptions.MinutesToTrack"/>.</param>
        /// <param name="minimumRequests">See <see cref="AdaptiveThrottlingOptions.MinimumRequests"/>.</param>
        /// <param name="criticalRatio">See <see cref="AdaptiveThrottlingOptions.CriticalRatio"/>.</param>
        /// <param name="maximumRejectProbability">See <see cref="AdaptiveThrottlingOptions.MaximumRejectProbability"/>.</param>
        public static void SetupAdaptiveThrottling(
            this IClusterClientConfiguration configuration,
            int minutesToTrack              = ClusterClientDefaults.AdaptiveThrottlingMinutesToTrack,
            int minimumRequests             = ClusterClientDefaults.AdaptiveThrottlingMinimumRequests,
            double criticalRatio            = ClusterClientDefaults.AdaptiveThrottlingCriticalRatio,
            double maximumRejectProbability = ClusterClientDefaults.AdaptiveThrottlingRejectProbabilityCap)
        {
            var storageKey = GenerateStorageKey(configuration.TargetEnvironment, configuration.TargetServiceName);

            SetupAdaptiveThrottling(configuration, storageKey, minutesToTrack, minimumRequests, criticalRatio, maximumRejectProbability);
        }
        public static void SetupSingular(this IClusterClientConfiguration configuration, SingularClientSettings settings)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            configuration.RequestTransforms.Add(
                new AdHocRequestTransform(
                    request => request
                    .WithHeader(SingularHeaders.Environment, settings.TargetEnvironment)
                    .WithHeader(SingularHeaders.Service, settings.TargetService)));

            configuration.TargetEnvironment = settings.TargetEnvironment;
            configuration.TargetServiceName = ServiceMeshEnvironmentInfo.UseLocalSingular
                ? $"{settings.TargetService} via ServiceMesh"
                : $"{settings.TargetService} via {SingularConstants.ServiceName}";

            var clusterConfigClient = ClusterConfigClient.Default;

            configuration.ClusterProvider = settings.AlternativeClusterProvider ??
                                            new ClusterConfigClusterProvider(clusterConfigClient, SingularConstants.CCTopologyName, configuration.Log);

            configuration.SetupWeighedReplicaOrdering(
                builder =>
            {
                var datacenters = DatacentersProvider.Get();
                builder.AddRelativeWeightModifier(new RelativeWeightSettings());
                builder.SetupAvoidInactiveDatacentersWeightModifier(datacenters);
                builder.SetupBoostLocalDatacentersWeightModifier(datacenters);
            });

            var forkingStrategy       = Strategy.Forking(SingularClientConstants.ForkingStrategyParallelismLevel);
            var idempotencyIdentifier = IdempotencyIdentifierCache.Get(clusterConfigClient, settings.TargetEnvironment, settings.TargetService);

            configuration.DefaultRequestStrategy = new IdempotencySignBasedRequestStrategy(idempotencyIdentifier, Strategy.Sequential1, forkingStrategy);

            configuration.MaxReplicasUsedPerRequest = SingularClientConstants.ForkingStrategyParallelismLevel;

            if (ServiceMeshEnvironmentInfo.UseLocalSingular)
            {
                var serviceMeshRequestModule = new ServiceMeshRequestModule(configuration.Log, idempotencyIdentifier);
                configuration.AddRequestModule(serviceMeshRequestModule, RequestModule.RequestExecution);
            }

            InitializeMetricsProviderIfNeeded(configuration, settings.MetricContext, clusterConfigClient);
        }
Ejemplo n.º 22
0
        /// <summary>
        /// <para>Adds given <paramref name="module"/> to configuration's <see cref="IClusterClientConfiguration.Modules"/> collection.</para>
        /// <para><paramref name="module"/> will be inserted into request module chain once around the module of specified type.</para>
        /// </summary>
        /// <param name="type">A type of module around which <paramref name="module"/> will be inserted.</param>
        /// <param name="module">A module to insert into request pipeline.</param>
        /// <param name="configuration">A configuration instance.</param>
        /// <param name="position">A relative position of <paramref name="module"/> from module of type <paramref name="type"/>. This parameter is optional and has default value <see cref="ModulePosition.Before"/>.</param>
        public static void AddRequestModule(
            this IClusterClientConfiguration configuration,
            IRequestModule module,
            Type type,
            ModulePosition position = ModulePosition.Before)
        {
            var modulesList = ObtainModules(configuration, type)[position];

            if (modulesList.All(m => m.GetType() != module.GetType()))
            {
                modulesList.Add(module);
            }
        }
Ejemplo n.º 23
0
        public void Apply(IClusterClientConfiguration config)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            config.Logging.LogReplicaRequests = false;
            config.Logging.LogResultDetails   = false;

            config.SetupUniversalTransport();
            config.SetupExternalUrlAsSingleReplicaCluster(externalUrl);
        }
Ejemplo n.º 24
0
        private static RelatedModules ObtainModules(IClusterClientConfiguration configuration, Type type)
        {
            if (configuration.Modules == null)
            {
                configuration.Modules = new Dictionary <Type, RelatedModules>();
            }

            if (!configuration.Modules.TryGetValue(type, out var modules))
            {
                configuration.Modules[type] = modules = new RelatedModules();
            }

            return(modules);
        }
        public static IList <IRequestModule> BuildChain(IClusterClientConfiguration config, IReplicaStorageProvider storageProvider)
        {
            var responseClassifier   = new ResponseClassifier();
            var requestConverter     = new RequestConverter(config.Log);
            var requestSender        = new RequestSender(config, storageProvider, responseClassifier, requestConverter, config.Transport);
            var resultStatusSelector = new ClusterResultStatusSelector();

            var modules = new List <IRequestModule>(15 + config.Modules?.Count ?? 0)
            {
                new ErrorCatchingModule(),
                new RequestTransformationModule(config.RequestTransforms),
                new OperationNameFallbackModule(),
                new RequestPriorityApplicationModule()
            };

            if (config.Modules != null)
            {
                modules.AddRange(config.Modules);
            }

            if (config.EnableTracing)
            {
                modules.Add(new TracingModule(config.ServiceName));
            }

            modules.Add(new LoggingModule(config.LogRequestDetails, config.LogResultDetails));
            modules.Add(new ResponseTransformationModule(config.ResponseTransforms));
            modules.Add(new ErrorCatchingModule());
            modules.Add(new RequestValidationModule());
            modules.Add(new TimeoutValidationModule());
            modules.Add(new RequestRetryModule(config.RetryPolicy, config.RetryStrategy));

            if (config.AdaptiveThrottling != null)
            {
                modules.Add(new AdaptiveThrottlingModule(config.AdaptiveThrottling));
            }

            if (config.ReplicaBudgeting != null)
            {
                modules.Add(new ReplicaBudgetingModule(config.ReplicaBudgeting));
            }

            modules.Add(new AbsoluteUrlSenderModule(config.Transport, responseClassifier, config.ResponseCriteria, resultStatusSelector));
            modules.Add(new RequestExecutionModule(config.ClusterProvider, config.ReplicaOrdering, config.ResponseSelector,
                                                   storageProvider, requestSender, resultStatusSelector));

            return(modules);
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Sets up an adaptive client throttling mechanism with given parameters.
        /// </summary>
        /// <param name="configuration">A configuration to be modified.</param>
        /// <param name="storageKey">See <see cref="AdaptiveThrottlingOptions.StorageKey"/>.</param>
        /// <param name="minutesToTrack">See <see cref="AdaptiveThrottlingOptions.MinutesToTrack"/>.</param>
        /// <param name="minimumRequests">See <see cref="AdaptiveThrottlingOptions.MinimumRequests"/>.</param>
        /// <param name="criticalRatio">See <see cref="AdaptiveThrottlingOptions.CriticalRatio"/>.</param>
        /// <param name="maximumRejectProbability">See <see cref="AdaptiveThrottlingOptions.MaximumRejectProbability"/>.</param>
        public static void SetupAdaptiveThrottling(
            this IClusterClientConfiguration configuration,
            string storageKey,
            int minutesToTrack              = ClusterClientDefaults.AdaptiveThrottlingMinutesToTrack,
            int minimumRequests             = ClusterClientDefaults.AdaptiveThrottlingMinimumRequests,
            double criticalRatio            = ClusterClientDefaults.AdaptiveThrottlingCriticalRatio,
            double maximumRejectProbability = ClusterClientDefaults.AdaptiveThrottlingRejectProbabilityCap)
        {
            var options = new AdaptiveThrottlingOptions(
                storageKey,
                minutesToTrack,
                minimumRequests,
                criticalRatio,
                maximumRejectProbability);

            configuration.AddRequestModule(new AdaptiveThrottlingModule(options), typeof(AbsoluteUrlSenderModule));
        }
        private static void InitializeMetricsProviderIfNeeded(IClusterClientConfiguration configuration, IMetricContext?metricContext, IClusterConfigClient clusterConfigClient)
        {
            if (metricContext == null && MetricContextProvider.IsConfigured)
            {
                metricContext = MetricContextProvider.Get();
            }

            if (metricContext != null)
            {
                var environment = clusterConfigClient.Get(SingularConstants.EnvironmentNamePath)?.Value;
                if (environment == SingularConstants.ProdEnvironment || environment == SingularConstants.CloudEnvironment)
                {
                    var metricsProvider = MetricsProviderCache.Get(metricContext, environment, SloMetricsClientName);
                    configuration.AddRequestModule(new MetricsModule(metricsProvider));
                }
            }
        }
        /// <summary>
        /// Sets up distributed tracing of HTTP requests using given <paramref name="configuration"/>.
        /// </summary>
        public static void SetupDistributedTracing([NotNull] this IClusterClientConfiguration config, [NotNull] TracingConfiguration configuration)
        {
            config.SetupDistributedContext();

            var tracingTransport = new TracingTransport(config.Transport, configuration)
            {
                TargetServiceProvider     = () => config.TargetServiceName,
                TargetEnvironmentProvider = () => config.TargetEnvironment
            };

            var tracingModule = new TracingModule(configuration)
            {
                TargetServiceProvider     = () => config.TargetServiceName,
                TargetEnvironmentProvider = () => config.TargetEnvironment
            };

            config.Transport = tracingTransport;
            config.AddRequestModule(tracingModule, typeof(DistributedContextModule));
        }
        public static void SetupExternalUrlAsSingleReplicaCluster(this IClusterClientConfiguration configuration, Uri url)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }
            if (url == null)
            {
                throw new ArgumentNullException(nameof(url));
            }
            if (!url.IsAbsoluteUri)
            {
                throw Errors.UrlShouldBeAbsolute(nameof(url), url);
            }

            configuration.ClusterProvider           = new FixedClusterProvider(url);
            configuration.MaxReplicasUsedPerRequest = 1;
            configuration.ReplicaOrdering           = new AsIsReplicaOrdering();
            configuration.SetupReplicaBudgeting(minimumRequests: 10);

            configuration.DefaultRequestStrategy = Strategy.Sequential1;
            configuration.DeduplicateRequestUrl  = true;
            configuration.TargetServiceName      = url.AbsoluteUri;
        }
Ejemplo n.º 30
0
 public static void SetupNativeTransport(this IClusterClientConfiguration self)
 {
     self.Transport = new NativeTransport(self.Log);
 }