/// <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)); }
/// <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); }
/// <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); }
/// <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);
/// <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); }
public void SetUp() { configuration = Substitute.For <IClusterClientConfiguration>(); underlyingTransport = Substitute.For <ITransport>(); transport = new TransportWithAuxiliaryHeaders(underlyingTransport, configuration); request = Request.Get("http://foo/bar"); }
/// <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); }
/// <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); }
/// <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); } }
internal static void ApplyReplicaTransform(this IClusterClientConfiguration configuration) { if (configuration.ReplicaTransform == null) { return; } configuration.ClusterProvider = new TransformingClusterProvider(configuration.ClusterProvider, configuration.ReplicaTransform); }
/// <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); }
/// <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); }
public RequestSender( IClusterClientConfiguration configuration, IReplicaStorageProvider storageProvider, IResponseClassifier responseClassifier, IRequestConverter requestConverter) { this.configuration = configuration; this.storageProvider = storageProvider; this.responseClassifier = responseClassifier; this.requestConverter = requestConverter; }
/// <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); }
/// <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); } }
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); }
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); }
/// <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; }
public static void SetupNativeTransport(this IClusterClientConfiguration self) { self.Transport = new NativeTransport(self.Log); }