コード例 #1
0
        public void Should_call_onBulkheadRejected_with_passed_context()
        {
            string  operationKey           = "SomeKey";
            Context contextPassedToExecute = new Context(operationKey);

            Context          contextPassedToOnRejected = null;
            Action <Context> onRejected = ctx => { contextPassedToOnRejected = ctx; };

            using (BulkheadPolicy bulkhead = Policy.Bulkhead(1, onRejected))
            {
                TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();

                Task.Run(() => { bulkhead.Execute(() => { tcs.Task.Wait(); }); });

                // Time for the other thread to kick up and take the bulkhead.
                Within(CohesionTimeLimit, () => Expect(0, () => bulkhead.BulkheadAvailableCount, nameof(bulkhead.BulkheadAvailableCount)));

                bulkhead.Invoking(b => b.Execute(ctx => { }, contextPassedToExecute)).Should()
                .Throw <BulkheadRejectedException>();

                tcs.SetCanceled();

                contextPassedToOnRejected.Should().NotBeNull();
                contextPassedToOnRejected.OperationKey.Should().Be(operationKey);
                contextPassedToOnRejected.Should().BeSameAs(contextPassedToExecute);
            }
        }
コード例 #2
0
 public PrintPollyBulkhead()
 {
     bulkheadPolicy = Policy.Bulkhead(2, 2, onBulkheadRejected: (context) =>
     {
         Console.WriteLine(context.Count);
     });
 }
コード例 #3
0
ファイル: BulkheadAsyncSpecs.cs プロジェクト: zlphoenix/Polly
        public void Should_call_onBulkheadRejected_with_passed_context()
        {
            string  executionKey           = Guid.NewGuid().ToString();
            Context contextPassedToExecute = new Context(executionKey);

            Context contextPassedToOnRejected    = null;
            Func <Context, Task> onRejectedAsync = async ctx => { contextPassedToOnRejected = ctx; await TaskHelper.EmptyTask.ConfigureAwait(false); };

            BulkheadPolicy bulkhead = Policy.BulkheadAsync(1, onRejectedAsync);

            TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();

            using (CancellationTokenSource cancellationSource = new CancellationTokenSource())
            {
                Task.Run(() => {
                    bulkhead.ExecuteAsync(async() =>
                    {
                        await tcs.Task.ConfigureAwait(false);
                    });
                });

                Within(shimTimeSpan, () => bulkhead.BulkheadAvailableCount.Should().Be(0)); // Time for the other thread to kick up and take the bulkhead.

                bulkhead.Awaiting(async b => await b.ExecuteAsync(() => TaskHelper.EmptyTask, contextPassedToExecute)).ShouldThrow <BulkheadRejectedException>();

                cancellationSource.Cancel();
                tcs.SetCanceled();
            }

            contextPassedToOnRejected.Should().NotBeNull();
            contextPassedToOnRejected.ExecutionKey.Should().Be(executionKey);
            contextPassedToOnRejected.Should().BeSameAs(contextPassedToExecute);
        }
コード例 #4
0
        public void Should_call_onBulkheadRejected_with_passed_context()
        {
            string  executionKey           = Guid.NewGuid().ToString();
            Context contextPassedToExecute = new Context(executionKey);

            Context          contextPassedToOnRejected = null;
            Action <Context> onRejected = ctx => { contextPassedToOnRejected = ctx; };

            BulkheadPolicy <int> bulkhead = Policy.Bulkhead <int>(1, onRejected);

            TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();

            using (CancellationTokenSource cancellationSource = new CancellationTokenSource())
            {
                Task.Run(() => {
                    bulkhead.Execute(() =>
                    {
                        tcs.Task.Wait();
                        return(0);
                    });
                });

                Within(shimTimeSpan, () => bulkhead.BulkheadAvailableCount.Should().Be(0)); // Time for the other thread to kick up and take the bulkhead.

                bulkhead.Invoking(b => b.Execute(() => 1, contextPassedToExecute)).ShouldThrow <BulkheadRejectedException>();

                cancellationSource.Cancel();
                tcs.SetCanceled();
            }

            contextPassedToOnRejected.Should().NotBeNull();
            contextPassedToOnRejected.ExecutionKey.Should().Be(executionKey);
            contextPassedToOnRejected.Should().BeSameAs(contextPassedToExecute);
        }
コード例 #5
0
 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="maxParallelization">此Policy可以最多并行执行的action 大于0</param>
 /// <param name="maxQueuingActions">The maxmimum number of actions that may be queuing, waiting for an execution slot. 大于等于0</param>
 /// <param name="onBulkheadRejected">当过多的action超出限制时执行的回调操作</param>
 public BulkheadEx(int maxParallelization, int maxQueuingActions, Action <Context> onBulkheadRejected = null)
 {
     _bulkhead = Policy.Bulkhead(maxParallelization, maxQueuingActions, context =>
     {
         onBulkheadRejected?.Invoke(context);
     });
 }
コード例 #6
0
        public void Should_call_onBulkheadRejected_with_passed_context()
        {
            string  operationKey           = "SomeKey";
            Context contextPassedToExecute = new Context(operationKey);

            Context          contextPassedToOnRejected = null;
            Action <Context> onRejected = ctx => { contextPassedToOnRejected = ctx; };

            using (BulkheadPolicy <int> bulkhead = Policy.Bulkhead <int>(1, onRejected))
            {
                TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();
                using (CancellationTokenSource cancellationSource = new CancellationTokenSource())
                {
                    Task.Run(() => {
                        bulkhead.Execute(() =>
                        {
                            tcs.Task.Wait();
                            return(0);
                        });
                    });

                    Within(CohesionTimeLimit, () => Expect(0, () => bulkhead.BulkheadAvailableCount, nameof(bulkhead.BulkheadAvailableCount)));

                    bulkhead.Invoking(b => b.Execute(_ => 1, contextPassedToExecute)).Should().Throw <BulkheadRejectedException>();

                    cancellationSource.Cancel();
                    tcs.SetCanceled();
                }

                contextPassedToOnRejected.Should().NotBeNull();
                contextPassedToOnRejected.OperationKey.Should().Be(operationKey);
                contextPassedToOnRejected.Should().BeSameAs(contextPassedToExecute);
            }
        }
コード例 #7
0
        private static IServiceProvider Register(IServiceCollection builder, IConfigurationRoot config)
        {
            builder
            .AddSingleton <OnNotificationEventTrigger>();

            builder
            .AddSingleton <INotificationService, NotificationService>();

            builder.AddFeatureToggling(config);

            builder.AddServiceBus(config);

            builder.AddApplicationInsights(config, "CalculateFunding.Functions.Notifications");
            builder.AddApplicationInsightsTelemetryClient(config, "CalculateFunding.Functions.Notifications");
            builder.AddLogging("CalculateFunding.Functions.Notifications");
            builder.AddTelemetry();

            builder.AddPolicySettings(config);

            builder.AddSingleton <INotificationsResiliencePolicies>((ctx) =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                return(new NotificationsResiliencePolicies
                {
                    MessagePolicy = ResiliencePolicyHelpers.GenerateMessagingPolicy(totalNetworkRequestsPolicy),
                });
            });

            return(builder.BuildServiceProvider());
        }
コード例 #8
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region Other ways of injecting policies
            //IAsyncPolicy<HttpResponseMessage> httpRetryPolicy =
            //   Policy.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode).RetryAsync(3);
            //services.AddHttpClient("RemoteServer", client =>
            //{
            //    client.BaseAddress = new Uri("http://aspnetmonsters.com");
            //    //client.DefaultRequestHeaders.Add("Accept", "application/json");
            //}).AddPolicyHandler(httpRetryPolicy);
            #endregion

            #region Advanced Circuit Breaker
            //CircuitBreakerPolicy<HttpResponseMessage> breakerPolicy = Policy
            //  .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
            //  .AdvancedCircuitBreakerAsync(0.5, TimeSpan.FromSeconds(60), 7, TimeSpan.FromSeconds(15),
            //      OnBreak, OnReset, OnHalfOpen);
            #endregion


            CircuitBreakerPolicy <HttpResponseMessage> breakerPolicy = Policy
                                                                       .HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode)
                                                                       .CircuitBreakerAsync(2, TimeSpan.FromSeconds(10), OnBreak, OnReset, OnHalfOpen);


            BulkheadPolicy <HttpResponseMessage> bulkheadIsolationPolicy = Policy
                                                                           .BulkheadAsync <HttpResponseMessage>(2, 4, onBulkheadRejectedAsync: OnBulkheadRejectedAsync);


            services.AddHttpClient("RemoteServer", client =>
            {
                client.BaseAddress = new Uri("http://aspnetmonsters.com");
                //client.DefaultRequestHeaders.Add("Accept", "application/json");
            });
            services.AddHttpClient("InventoryClient", client =>
            {
                client.BaseAddress = new Uri("http://localhost:57697/api/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Add("Accept", "application/json");
            }).
            ConfigurePrimaryHttpMessageHandler(handler => new HttpClientHandler
            {
                AutomaticDecompression = DecompressionMethods.GZip
            });

            IAsyncPolicy <HttpResponseMessage> httpRetryPolicy =
                Policy.HandleResult <HttpResponseMessage>(r => !r.IsSuccessStatusCode)
                .RetryAsync(3);

            services.AddSingleton <IAsyncPolicy <HttpResponseMessage> >(httpRetryPolicy);

            services.AddSingleton <CircuitBreakerPolicy <HttpResponseMessage> >(breakerPolicy);
            services.AddSingleton <BulkheadPolicy <HttpResponseMessage> >(bulkheadIsolationPolicy);
            services.AddSingleton(CustomPolicyWrap());

            services.AddSingleton <PolicyHolder>(new PolicyHolder());
            services.AddSingleton <IPolicyRegistry <string> >(GetRegistry());
            services.AddMvc();
        }
コード例 #9
0
ファイル: TraceableAction.cs プロジェクト: arun6202/XamlSync
        // Note re TaskCreationOptions.LongRunning: Testing the parallelization of the bulkhead policy efficiently requires the ability to start large numbers of parallel tasks in a short space of time.  The ThreadPool's algorithm of only injecting extra threads (when necessary) at a rate of two-per-second however makes high-volume tests using the ThreadPool both slow and flaky.  For PCL tests further, ThreadPool.SetMinThreads(...) is not available, to mitigate this.  Using TaskCreationOptions.LongRunning allows us to force tasks to be started near-instantly on non-ThreadPool threads.
        // Similarly, we use ConfigureAwait(true) when awaiting, to avoid continuations being scheduled onto a ThreadPool thread, which may only be injected too slowly in high-volume tests.

        public Task ExecuteOnBulkhead(BulkheadPolicy bulkhead)
        {
            if (Status != TraceableActionStatus.Unstarted)
            {
                throw new InvalidOperationException(_id + "Action has previously been started.");
            }
            Status = TraceableActionStatus.StartRequested;

            return(Task.Factory.StartNew(() =>
            {
                try
                {
                    Status = TraceableActionStatus.QueueingForSemaphore;

                    bulkhead.Execute(ct =>
                    {
                        Status = TraceableActionStatus.Executing;

                        _tcsProxyForRealWork.Task.ContinueWith(CaptureCompletion()).Wait();

                        _testOutputHelper.WriteLine(_id + "Exiting execution.");
                    }, CancellationSource.Token);
                }
                catch (BulkheadRejectedException)
                {
                    Status = TraceableActionStatus.Rejected;
                }
                catch (OperationCanceledException)
                {
                    if (Status != TraceableActionStatus.Canceled)
                    {
                        _testOutputHelper.WriteLine(_id + "Caught queue cancellation.");
                        Status = TraceableActionStatus.Canceled;
                    } // else: was execution cancellation rethrown: ignore
                }
                catch (AggregateException ae)
                {
                    if (ae.InnerExceptions.Count == 1 && ae.InnerException is OperationCanceledException)
                    {
                        if (Status != TraceableActionStatus.Canceled)
                        {
                            _testOutputHelper.WriteLine(_id + "Caught queue cancellation.");
                            Status = TraceableActionStatus.Canceled;
                        } // else: was execution cancellation rethrown: ignore
                    }
                    else
                    {
                        throw;
                    }
                }
                catch (Exception e)
                {
                    _testOutputHelper.WriteLine(_id + "Caught unexpected exception during execution: " + e);

                    Status = TraceableActionStatus.Faulted;
                }
            },
                                         TaskCreationOptions.LongRunning));
        }
コード例 #10
0
ファイル: PollyTraining.cs プロジェクト: lv-conner/AOP
 public PollyTraining()
 {
     _proxy = Policy.BulkheadAsync(2, 1, c =>
     {
         Console.WriteLine("reject request");
         return(Task.CompletedTask);
     });
 }
コード例 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WorkGroupWithItem"/> class.
        /// </summary>
        /// <param name="sourceGroup">The source group.</param>
        /// <param name="threadGroup">The thread group.</param>
        /// <param name="metricCounter">A counter for tracking how many items are being processed</param>
        public WorkGroupWithItem(IWorkGroup sourceGroup, BulkheadPolicy threadGroup, ICounter metricCounter)
        {
            Guard.NotNull(() => sourceGroup, sourceGroup);
            Guard.NotNull(() => threadGroup, threadGroup);
            Guard.NotNull(() => metricCounter, metricCounter);

            GroupInfo     = sourceGroup;
            Group         = threadGroup;
            MaxWorkItems  = GroupInfo.ConcurrencyLevel + GroupInfo.MaxQueueSize;
            MetricCounter = metricCounter;
        }
コード例 #12
0
ファイル: TraceableAction.cs プロジェクト: arun6202/XamlSync
        public Task <TResult> ExecuteOnBulkheadAsync <TResult>(BulkheadPolicy <TResult> bulkhead)
        {
            if (Status != TraceableActionStatus.Unstarted)
            {
                throw new InvalidOperationException(_id + "Action has previously been started.");
            }
            Status = TraceableActionStatus.StartRequested;

            TResult result = default(TResult);

            return(Task.Factory.StartNew(async() =>
            {
                try
                {
                    Status = TraceableActionStatus.QueueingForSemaphore;

                    result = await bulkhead.ExecuteAsync(async ct =>
                    {
                        Status = TraceableActionStatus.Executing;

                        await _tcsProxyForRealWork.Task.ContinueWith(CaptureCompletion()).ConfigureAwait(true);

                        _testOutputHelper.WriteLine(_id + "Exiting execution.");

                        return default(TResult);
                    }, CancellationSource.Token).ConfigureAwait(true);
                }
                catch (BulkheadRejectedException)
                {
                    Status = TraceableActionStatus.Rejected;
                }
                catch (OperationCanceledException)
                {
                    if (Status != TraceableActionStatus.Canceled)
                    {
                        _testOutputHelper.WriteLine(_id + "Caught queue cancellation.");
                        Status = TraceableActionStatus.Canceled;
                    } // else: was execution cancellation rethrown: ignore
                }
                catch (Exception e)
                {
                    _testOutputHelper.WriteLine(_id + "Caught unexpected exception during execution: " + e);

                    Status = TraceableActionStatus.Faulted;
                }
                return result;
            }
                                         , TaskCreationOptions.LongRunning).Unwrap());
        }
コード例 #13
0
ファイル: Startup.cs プロジェクト: melih154/CFS-Backend
        private static CalculatorResiliencePolicies CreateResiliencePolicies(PolicySettings policySettings)
        {
            BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

            CalculatorResiliencePolicies resiliencePolicies = new CalculatorResiliencePolicies()
            {
                ProviderResultsRepository        = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                ProviderSourceDatasetsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                CacheProvider          = ResiliencePolicyHelpers.GenerateRedisPolicy(totalNetworkRequestsPolicy),
                Messenger              = ResiliencePolicyHelpers.GenerateMessagingPolicy(totalNetworkRequestsPolicy),
                CalculationsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                JobsApiClient          = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy)
            };

            return(resiliencePolicies);
        }
コード例 #14
0
        /// <inheritdoc />
        public override void Start()
        {
            ThrowIfDisposed();
            Guard.IsValid(() => Configuration.MaximumThreads, Configuration.MaximumThreads, i => i > 0,
                          "The Configuration.MaximumThreads must be greater than 0");

            if (_smartThreadPool != null)
            {
                throw new DotNetWorkQueueException("Start must only be called 1 time");
            }

            _smartThreadPool = Policy.Bulkhead(_configuration.MaximumThreads,
                                               _configuration.MaxQueueSize, OnBulkheadRejected);

            Configuration.SetReadOnly();
        }
コード例 #15
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            BulkheadPolicy <HttpResponseMessage> bulkheadIsolationPolicy = Policy
                                                                           .BulkheadAsync <HttpResponseMessage>(2, 4, onBulkheadRejectedAsync: OnBulkheadRejectedAsync);

            HttpClient httpClient = new HttpClient()
            {
                BaseAddress = new Uri("http://localhost:57696/api/") // this is the endpoint HttpClient will hit,
            };

            httpClient.DefaultRequestHeaders.Accept.Clear();
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            services.AddSingleton <HttpClient>(httpClient);
            services.AddSingleton <BulkheadPolicy <HttpResponseMessage> >(bulkheadIsolationPolicy);
            services.AddMvc();
        }
コード例 #16
0
        private static ResiliencePolicies CreateResiliencePolicies(PolicySettings policySettings)
        {
            BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

            return(new ResiliencePolicies
            {
                CalculationsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                CalculationsSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                CacheProviderPolicy = ResiliencePolicyHelpers.GenerateRedisPolicy(totalNetworkRequestsPolicy),
                CalculationsVersionsRepositoryPolicy = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                SpecificationsRepositoryPolicy = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                BuildProjectRepositoryPolicy = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                MessagePolicy = ResiliencePolicyHelpers.GenerateMessagingPolicy(totalNetworkRequestsPolicy),
                JobsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                SourceFilesRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                DatasetsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy)
            });
        }
コード例 #17
0
        private static ResiliencePolicies CreateResiliencePolicies(PolicySettings policySettings)
        {
            BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

            ResiliencePolicies resiliencePolicies = new ResiliencePolicies()
            {
                CalculationProviderResultsSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                ResultsRepository        = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                ResultsSearchRepository  = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                SpecificationsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                AllocationNotificationFeedSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                ProviderProfilingRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                PublishedProviderCalculationResultsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                PublishedProviderResultsRepository            = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                CalculationsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                JobsApiClient          = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                ProviderCalculationResultsSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                ProviderChangesRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                CsvBlobPolicy             = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
            };

            return(resiliencePolicies);
        }
コード例 #18
0
        public void Should_control_executions_queuing_and_rejections_per_specification_with_cancellations(
            int maxParallelization, int maxQueuingActions, int totalActions, bool cancelQueuing,
            bool cancelExecuting, string scenario)
        {
            if (totalActions < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(totalActions));
            }
            scenario = String.Format("MaxParallelization {0}; MaxQueuing {1}; TotalActions {2}; CancelQueuing {3}; CancelExecuting {4}: {5}", maxParallelization, maxQueuingActions, totalActions, cancelQueuing, cancelExecuting, scenario);

            BulkheadPolicy <ResultPrimitive> bulkhead = Policy.Bulkhead <ResultPrimitive>(maxParallelization, maxQueuingActions);

            // Set up delegates which we can track whether they've started; and control when we allow them to complete (to release their semaphore slot).
            actions = new TraceableAction[totalActions];
            for (int i = 0; i < totalActions; i++)
            {
                actions[i] = new TraceableAction(i, statusChanged, testOutputHelper);
            }

            // Throw all the delegates at the bulkhead simultaneously.
            Task[] tasks = new Task[totalActions];
            for (int i = 0; i < totalActions; i++)
            {
                tasks[i] = actions[i].ExecuteOnBulkhead(bulkhead);
            }

            testOutputHelper.WriteLine("Immediately after queueing...");
            testOutputHelper.WriteLine("Bulkhead: {0} slots out of {1} available.", bulkhead.BulkheadAvailableCount, maxParallelization);
            testOutputHelper.WriteLine("Bulkhead queue: {0} slots out of {1} available.", bulkhead.QueueAvailableCount, maxQueuingActions);
            OutputActionStatuses();

            // Assert the expected distributions of executing, queuing, rejected and completed - when all delegates thrown at bulkhead.
            int expectedCompleted    = 0;
            int expectedCancelled    = 0;
            int expectedExecuting    = Math.Min(totalActions, maxParallelization);
            int expectedRejects      = Math.Max(0, totalActions - maxParallelization - maxQueuingActions);
            int expectedQueuing      = Math.Min(maxQueuingActions, Math.Max(0, totalActions - maxParallelization));
            int expectedBulkheadFree = maxParallelization - expectedExecuting;
            int expectedQueueFree    = maxQueuingActions - expectedQueuing;

            try
            {
                actions.Count(a => a.Status == TraceableActionStatus.Faulted).Should().Be(0);
                Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.Executing).Should().Be(expectedExecuting, scenario + ", when checking expectedExecuting"));
                Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.QueueingForSemaphore).Should().Be(expectedQueuing, scenario + ", when checking expectedQueuing"));
                Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.Rejected).Should().Be(expectedRejects, scenario + ", when checking expectedRejects"));
                actions.Count(a => a.Status == TraceableActionStatus.Completed).Should().Be(expectedCompleted, scenario + ", when checking expectedCompleted");
                actions.Count(a => a.Status == TraceableActionStatus.Canceled).Should().Be(expectedCancelled, scenario + ", when checking expectedCancelled");
                Within(shimTimeSpan, () => bulkhead.BulkheadAvailableCount.Should().Be(expectedBulkheadFree, scenario + ", when checking expectedBulkheadFree"));
                Within(shimTimeSpan, () => bulkhead.QueueAvailableCount.Should().Be(expectedQueueFree, scenario + ", when checking expectedQueueFree"));
            }
            finally
            {
                testOutputHelper.WriteLine("Expected initial state verified...");
                testOutputHelper.WriteLine("Bulkhead: {0} slots out of {1} available.", bulkhead.BulkheadAvailableCount, maxParallelization);
                testOutputHelper.WriteLine("Bulkhead queue: {0} slots out of {1} available.", bulkhead.QueueAvailableCount, maxQueuingActions);
                OutputActionStatuses();
            }

            // Complete or cancel delegates one by one, and expect others to take their place (if a slot released and others remain queueing); until all work is done.
            while (expectedExecuting > 0)
            {
                if (cancelQueuing)
                {
                    testOutputHelper.WriteLine("Cancelling a queueing task...");

                    actions.First(a => a.Status == TraceableActionStatus.QueueingForSemaphore).Cancel();

                    expectedCancelled++;
                    expectedQueuing--;
                    expectedQueueFree++;

                    cancelQueuing = false;
                }
                else if (cancelExecuting)
                {
                    testOutputHelper.WriteLine("Cancelling an executing task...");

                    actions.First(a => a.Status == TraceableActionStatus.Executing).Cancel();

                    expectedCancelled++;
                    if (expectedQueuing > 0)
                    {
                        expectedQueuing--;
                        expectedQueueFree++;
                    }
                    else
                    {
                        expectedExecuting--;
                        expectedBulkheadFree++;
                    }

                    cancelExecuting = false;
                }
                else // Complete an executing delegate.
                {
                    testOutputHelper.WriteLine("Completing a task...");

                    actions.First(a => a.Status == TraceableActionStatus.Executing).AllowCompletion();

                    expectedCompleted++;

                    if (expectedQueuing > 0)
                    {
                        expectedQueuing--;
                        expectedQueueFree++;
                    }
                    else
                    {
                        expectedExecuting--;
                        expectedBulkheadFree++;
                    }
                }
                try
                {
                    actions.Count(a => a.Status == TraceableActionStatus.Faulted).Should().Be(0);
                    Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.Executing).Should().Be(expectedExecuting, scenario + ", when checking expectedExecuting"));
                    Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.QueueingForSemaphore).Should().Be(expectedQueuing, scenario + ", when checking expectedQueuing"));
                    Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.Completed).Should().Be(expectedCompleted, scenario + ", when checking expectedCompleted"));
                    Within(shimTimeSpan, () => actions.Count(a => a.Status == TraceableActionStatus.Canceled).Should().Be(expectedCancelled, scenario + ", when checking expectedCancelled"));
                    actions.Count(a => a.Status == TraceableActionStatus.Rejected).Should().Be(expectedRejects, scenario + ", when checking expectedRejects");
                    Within(shimTimeSpan, () => bulkhead.BulkheadAvailableCount.Should().Be(expectedBulkheadFree, scenario + ", when checking expectedBulkheadFree"));
                    Within(shimTimeSpan, () => bulkhead.QueueAvailableCount.Should().Be(expectedQueueFree, scenario + ", when checking expectedQueueFree"));
                }
                finally
                {
                    testOutputHelper.WriteLine("End of next loop iteration...");
                    testOutputHelper.WriteLine("Bulkhead: {0} slots out of {1} available.", bulkhead.BulkheadAvailableCount, maxParallelization);
                    testOutputHelper.WriteLine("Bulkhead queue: {0} slots out of {1} available.", bulkhead.QueueAvailableCount, maxQueuingActions);
                    OutputActionStatuses();
                }
            }

            EnsureNoUnbservedTaskExceptions(tasks);
            testOutputHelper.WriteLine("Verifying all tasks completed...");
            Within(shimTimeSpan, () => tasks.All(t => t.IsCompleted).Should().BeTrue());

            #endregion
        }
コード例 #19
0
        public void RegisterComponents(IServiceCollection builder)
        {
            builder.AddSingleton <ISpecificationsRepository, SpecificationsRepository>();
            builder
            .AddSingleton <ISpecificationsService, SpecificationsService>()
            .AddSingleton <IHealthChecker, SpecificationsService>();
            builder.AddSingleton <IValidator <PolicyCreateModel>, PolicyCreateModelValidator>();
            builder.AddSingleton <IValidator <PolicyEditModel>, PolicyEditModelValidator>();
            builder.AddSingleton <IValidator <CalculationCreateModel>, CalculationCreateModelValidator>();
            builder.AddSingleton <IValidator <SpecificationCreateModel>, SpecificationCreateModelValidator>();
            builder.AddSingleton <IValidator <CalculationEditModel>, CalculationEditModelValidator>();
            builder.AddSingleton <IValidator <SpecificationEditModel>, SpecificationEditModelValidator>();
            builder.AddSingleton <IValidator <AssignDefinitionRelationshipMessage>, AssignDefinitionRelationshipMessageValidator>();
            builder
            .AddSingleton <ISpecificationsSearchService, SpecificationsSearchService>()
            .AddSingleton <IHealthChecker, SpecificationsSearchService>();
            builder.AddSingleton <IResultsRepository, ResultsRepository>();
            builder.AddSingleton <ICalculationsRepository, CalculationsRepository>();
            builder.AddSingleton <IFundingService, FundingService>();

            builder.AddSingleton <ICosmosRepository, CosmosRepository>();

            builder.AddSingleton <IVersionRepository <SpecificationVersion>, VersionRepository <SpecificationVersion> >((ctx) =>
            {
                CosmosDbSettings specsVersioningDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", specsVersioningDbSettings);

                specsVersioningDbSettings.CollectionName = "specs";

                CosmosRepository resultsRepostory = new CosmosRepository(specsVersioningDbSettings);

                return(new VersionRepository <SpecificationVersion>(resultsRepostory));
            });

            MapperConfiguration mappingConfig = new MapperConfiguration(c => c.AddProfile <SpecificationsMappingProfile>());

            builder.AddFeatureToggling(Configuration);

            builder.AddSingleton(mappingConfig.CreateMapper());

            builder.AddUserProviderFromRequest();

            builder.AddCosmosDb(Configuration);

            builder.AddServiceBus(Configuration);

            builder.AddSearch(Configuration);

            builder.AddCaching(Configuration);

            builder.AddResultsInterServiceClient(Configuration);
            builder.AddJobsInterServiceClient(Configuration);
            builder.AddCalcsInterServiceClient(Configuration);

            builder.AddPolicySettings(Configuration);

            builder.AddSingleton <ISpecificationsResiliencePolicies>((ctx) =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                Polly.Policy redisPolicy = ResiliencePolicyHelpers.GenerateRedisPolicy(totalNetworkRequestsPolicy);

                return(new SpecificationsResiliencePolicies()
                {
                    JobsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy)
                });
            });

            builder.AddApplicationInsights(Configuration, "CalculateFunding.Api.Specs");
            builder.AddApplicationInsightsTelemetryClient(Configuration, "CalculateFunding.Apis.Specs");
            builder.AddLogging("CalculateFunding.Apis.Specs");
            builder.AddTelemetry();

            builder.AddApiKeyMiddlewareSettings((IConfigurationRoot)Configuration);

            builder.AddHttpContextAccessor();

            builder.AddHealthCheckMiddleware();
        }
コード例 #20
0
ファイル: Startup.cs プロジェクト: melih154/CFS-Backend
        public void RegisterComponents(IServiceCollection builder)
        {
            builder
            .AddSingleton <IJobDefinitionsService, JobDefinitionsService>()
            .AddSingleton <IHealthChecker, JobDefinitionsService>();

            builder
            .AddSingleton <IJobService, JobService>()
            .AddSingleton <IHealthChecker, JobService>();

            builder
            .AddSingleton <INotificationService, NotificationService>();

            builder
            .AddSingleton <IJobManagementService, JobManagementService>()
            .AddSingleton <IHealthChecker, JobManagementService>();

            builder.
            AddSingleton <IValidator <CreateJobValidationModel>, CreateJobValidator>();

            builder
            .AddSingleton <IJobDefinitionsRepository, JobDefinitionsRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "jobdefinitions";

                CosmosRepository jobDefinitionsCosmosRepostory = new CosmosRepository(cosmosDbSettings);

                return(new JobDefinitionsRepository(jobDefinitionsCosmosRepostory));
            });

            builder
            .AddSingleton <IJobRepository, JobRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "jobs";

                CosmosRepository jobCosmosRepostory = new CosmosRepository(cosmosDbSettings);

                return(new JobRepository(jobCosmosRepostory));
            });

            MapperConfiguration mappingConfig = new MapperConfiguration(c => c.AddProfile <JobsMappingProfile>());

            builder.AddSingleton(mappingConfig.CreateMapper());

            builder.AddApplicationInsights(Configuration, "CalculateFunding.Api.Jobs");
            builder.AddApplicationInsightsTelemetryClient(Configuration, "CalculateFunding.Api.Jobs");
            builder.AddLogging("CalculateFunding.Api.Jobs");
            builder.AddTelemetry();

            builder.AddApiKeyMiddlewareSettings((IConfigurationRoot)Configuration);

            builder.AddPolicySettings(Configuration);

            builder.AddCaching(Configuration);

            builder.AddServiceBus(Configuration);

            builder.AddSingleton <IJobsResiliencePolicies>((ctx) =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                BulkheadPolicy totalNetworkRequestsPolicy         = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);
                BulkheadPolicy totalNetworkRequestsPolicyNonAsync = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsNonAsyncPolicy(policySettings);
                return(new ResiliencePolicies
                {
                    JobDefinitionsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    CacheProviderPolicy = ResiliencePolicyHelpers.GenerateRedisPolicy(totalNetworkRequestsPolicy),
                    JobRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    JobRepositoryNonAsync = CosmosResiliencePolicyHelper.GenerateNonAsyncCosmosPolicy(totalNetworkRequestsPolicyNonAsync),
                    MessengerServicePolicy = ResiliencePolicyHelpers.GenerateMessagingPolicy(totalNetworkRequestsPolicy)
                });
            });

            builder.AddHealthCheckMiddleware();
        }
コード例 #21
0
ファイル: Startup.cs プロジェクト: melih154/CFS-Backend
        public void RegisterComponents(IServiceCollection builder)
        {
            builder
            .AddSingleton <ICalculationsRepository, CalculationsRepository>();

            builder
            .AddSingleton <ICalculationService, CalculationService>()
            .AddSingleton <IHealthChecker, CalculationService>();

            builder
            .AddSingleton <ICalculationCodeReferenceUpdate, CalculationCodeReferenceUpdate>()
            .AddSingleton <ITokenChecker, TokenChecker>();

            builder
            .AddSingleton <ICalculationsSearchService, CalculationSearchService>()
            .AddSingleton <IHealthChecker, CalculationSearchService>();

            builder
            .AddSingleton <IValidator <Calculation>, CalculationModelValidator>();

            builder
            .AddSingleton <IPreviewService, PreviewService>()
            .AddSingleton <IHealthChecker, PreviewService>();

            builder
            .AddSingleton <ICompilerFactory, CompilerFactory>();

            builder
            .AddSingleton <CSharpCompiler>()
            .AddSingleton <VisualBasicCompiler>()
            .AddSingleton <VisualBasicSourceFileGenerator>();

            builder
            .AddSingleton <ISourceFileGeneratorProvider, SourceFileGeneratorProvider>();

            builder
            .AddSingleton <IValidator <PreviewRequest>, PreviewRequestModelValidator>();

            builder
            .AddSingleton <IProviderResultsRepository, ProviderResultsRepository>()
            .AddSingleton <IHealthChecker, ProviderResultsRepository>();

            builder
            .AddSingleton <ISpecificationRepository, SpecificationRepository>();

            builder
            .AddSingleton <IBuildProjectsService, BuildProjectsService>()
            .AddSingleton <IHealthChecker, BuildProjectsService>();

            builder
            .AddSingleton <IBuildProjectsRepository, BuildProjectsRepository>()
            .AddSingleton <IHealthChecker, BuildProjectsRepository>();

            builder
            .AddSingleton <ICodeMetadataGeneratorService, ReflectionCodeMetadataGenerator>();

            builder
            .AddSingleton <IDatasetRepository, DatasetRepository>();

            builder.AddSingleton <ISourceCodeService, SourceCodeService>();

            builder
            .AddSingleton <IDatasetDefinitionFieldChangesProcessor, DatasetDefinitionFieldChangesProcessor>();

            builder.AddSingleton <ISourceFileRepository, SourceFileRepository>((ctx) =>
            {
                BlobStorageOptions blobStorageOptions = new BlobStorageOptions();

                Configuration.Bind("CommonStorageSettings", blobStorageOptions);

                blobStorageOptions.ContainerName = "source";

                return(new SourceFileRepository(blobStorageOptions));
            });

            builder.AddSingleton <IVersionRepository <CalculationVersion>, VersionRepository <CalculationVersion> >((ctx) =>
            {
                CosmosDbSettings calcsVersioningDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", calcsVersioningDbSettings);

                calcsVersioningDbSettings.CollectionName = "calcs";

                CosmosRepository resultsRepostory = new CosmosRepository(calcsVersioningDbSettings);

                return(new VersionRepository <CalculationVersion>(resultsRepostory));
            });

            builder
            .AddSingleton <ICancellationTokenProvider, HttpContextCancellationProvider>();

            builder.AddUserProviderFromRequest();

            builder.AddCosmosDb(Configuration);

            builder.AddSearch(Configuration);

            builder.AddServiceBus(Configuration);

            builder.AddResultsInterServiceClient(Configuration);
            builder.AddSpecificationsInterServiceClient(Configuration);
            builder.AddDatasetsInterServiceClient(Configuration);
            builder.AddJobsInterServiceClient(Configuration);

            builder.AddCaching(Configuration);

            builder.AddApplicationInsights(Configuration, "CalculateFunding.Api.Calcs");
            builder.AddApplicationInsightsTelemetryClient(Configuration, "CalculateFunding.Api.Calcs");
            builder.AddLogging("CalculateFunding.Api.Calcs");
            builder.AddTelemetry();

            builder.AddEngineSettings(Configuration);

            builder.AddFeatureToggling(Configuration);

            builder.AddPolicySettings(Configuration);

            builder.AddSingleton <ICalcsResiliencePolicies>((ctx) =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                return(new ResiliencePolicies
                {
                    CalculationsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    CalculationsSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                    CacheProviderPolicy = ResiliencePolicyHelpers.GenerateRedisPolicy(totalNetworkRequestsPolicy),
                    CalculationsVersionsRepositoryPolicy = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    SpecificationsRepositoryPolicy = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    BuildProjectRepositoryPolicy = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    MessagePolicy = ResiliencePolicyHelpers.GenerateMessagingPolicy(totalNetworkRequestsPolicy),
                    JobsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    SourceFilesRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    DatasetsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy)
                });
            });

            builder.AddApiKeyMiddlewareSettings((IConfigurationRoot)Configuration);

            builder.AddHttpContextAccessor();

            builder.AddHealthCheckMiddleware();
        }
コード例 #22
0
        public void RegisterComponents(IServiceCollection builder)
        {
            builder
            .AddSingleton <IDefinitionsService, DefinitionsService>()
            .AddSingleton <IHealthChecker, DefinitionsService>();

            builder
            .AddSingleton <IDatasetService, DatasetService>()
            .AddSingleton <IHealthChecker, DatasetService>();

            builder
            .AddSingleton <IProcessDatasetService, ProcessDatasetService>()
            .AddSingleton <IHealthChecker, ProcessDatasetService>();

            builder
            .AddSingleton <IValidator <CreateNewDatasetModel>, CreateNewDatasetModelValidator>();

            builder
            .AddSingleton <IValidator <DatasetVersionUpdateModel>, DatasetVersionUpdateModelValidator>();

            builder
            .AddSingleton <IValidator <DatasetMetadataModel>, DatasetMetadataModelValidator>();

            builder
            .AddSingleton <IValidator <GetDatasetBlobModel>, GetDatasetBlobModelValidator>();

            builder
            .AddSingleton <IValidator <CreateDefinitionSpecificationRelationshipModel>, CreateDefinitionSpecificationRelationshipModelValidator>();

            builder
            .AddSingleton <IExcelWriter <DatasetDefinition>, DataDefinitionExcelWriter>();

            builder
            .AddSingleton <IValidator <ExcelPackage>, DatasetWorksheetValidator>();

            builder
            .AddSingleton <IDefinitionChangesDetectionService, DefinitionChangesDetectionService>();

            builder
            .AddSingleton <IDatasetDefinitionNameChangeProcessor, DatasetDefinitionNameChangeProcessor>();

            builder
            .AddSingleton <IBlobClient, BlobClient>((ctx) =>
            {
                AzureStorageSettings storageSettings = new AzureStorageSettings();

                Configuration.Bind("AzureStorageSettings", storageSettings);

                storageSettings.ContainerName = "datasets";

                return(new BlobClient(storageSettings));
            });

            builder.AddSingleton <IProvidersResultsRepository, ProvidersResultsRepository>((ctx) =>
            {
                CosmosDbSettings dbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", dbSettings);

                dbSettings.CollectionName = "providerdatasets";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(dbSettings);

                return(new ProvidersResultsRepository(calcsCosmosRepostory));
            });

            builder.AddSingleton <IDatasetsAggregationsRepository, DatasetsAggregationsRepository>((ctx) =>
            {
                CosmosDbSettings dbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", dbSettings);

                dbSettings.CollectionName = "datasetaggregations";

                CosmosRepository aggsCosmosRepostory = new CosmosRepository(dbSettings);

                return(new DatasetsAggregationsRepository(aggsCosmosRepostory));
            });

            builder.AddSingleton <IVersionRepository <ProviderSourceDatasetVersion>, VersionRepository <ProviderSourceDatasetVersion> >((ctx) =>
            {
                CosmosDbSettings ProviderSourceDatasetVersioningDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", ProviderSourceDatasetVersioningDbSettings);

                ProviderSourceDatasetVersioningDbSettings.CollectionName = "providersources";

                CosmosRepository cosmosRepository = new CosmosRepository(ProviderSourceDatasetVersioningDbSettings);

                return(new VersionRepository <ProviderSourceDatasetVersion>(cosmosRepository));
            });

            builder.AddSingleton <IDatasetRepository, DataSetsRepository>();

            builder.AddSingleton <IDatasetSearchService, DatasetSearchService>()
            .AddSingleton <IHealthChecker, DatasetSearchService>();

            builder.AddSingleton <IDatasetDefinitionSearchService, DatasetDefinitionSearchService>();

            builder
            .AddSingleton <IDefinitionSpecificationRelationshipService, DefinitionSpecificationRelationshipService>()
            .AddSingleton <IHealthChecker, DefinitionSpecificationRelationshipService>();

            builder
            .AddSingleton <ISpecificationsRepository, SpecificationsRepository>();

            builder
            .AddSingleton <IExcelDatasetReader, ExcelDatasetReader>();

            builder
            .AddSingleton <IProviderService, ProviderService>();

            builder
            .AddSingleton <ICalcsRepository, CalcsRepository>();

            builder
            .AddSingleton <IResultsRepository, ResultsRepository>();

            builder
            .AddSingleton <ICancellationTokenProvider, HttpContextCancellationProvider>();


            MapperConfiguration dataSetsConfig = new MapperConfiguration(c =>
            {
                c.AddProfile <DatasetsMappingProfile>();
                c.AddProfile <ProviderMappingProfile>();
            });

            builder
            .AddSingleton(dataSetsConfig.CreateMapper());

            builder.AddUserProviderFromRequest();

            builder.AddCalcsInterServiceClient(Configuration);
            builder.AddResultsInterServiceClient(Configuration);
            builder.AddSpecificationsInterServiceClient(Configuration);
            builder.AddJobsInterServiceClient(Configuration);

            builder.AddCosmosDb(Configuration);

            builder.AddSearch(Configuration);

            builder.AddServiceBus(Configuration);

            builder.AddCaching(Configuration);

            builder.AddFeatureToggling(Configuration);

            builder.AddApplicationInsights(Configuration, "CalculateFunding.Api.Datasets");
            builder.AddApplicationInsightsTelemetryClient(Configuration, "CalculateFunding.Api.Datasets");
            builder.AddLogging("CalculateFunding.Api.Datasets");
            builder.AddTelemetry();

            builder.AddApiKeyMiddlewareSettings((IConfigurationRoot)Configuration);

            builder.AddPolicySettings(Configuration);

            builder.AddHttpContextAccessor();

            builder.AddSingleton <IDatasetsResiliencePolicies>((ctx) =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                Policy redisPolicy = ResiliencePolicyHelpers.GenerateRedisPolicy(totalNetworkRequestsPolicy);

                return(new DatasetsResiliencePolicies()
                {
                    SpecificationsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    CacheProviderRepository = redisPolicy,
                    ProviderResultsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    ProviderRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    DatasetRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    DatasetSearchService = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                    DatasetDefinitionSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                    BlobClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    JobsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy)
                });
            });

            builder.AddTransient <IValidator <DatasetUploadValidationModel>, DatasetItemValidator>();

            builder.AddSingleton <IProviderService, ProviderService>();

            builder.AddHealthCheckMiddleware();
        }
コード例 #23
0
ファイル: Startup.cs プロジェクト: melih154/CFS-Backend
        public void RegisterComponents(IServiceCollection builder)
        {
            builder.AddFeatureToggling(Configuration);

            // Register v1 services
            builder
            .AddSingleton <V1.Interfaces.IAllocationNotificationFeedsService, V1.Services.AllocationNotificationFeedsService>();
            builder
            .AddSingleton <V1.Interfaces.IProviderResultsService, V1.Services.ProviderResultsService>();
            builder
            .AddSingleton <V1.Interfaces.IAllocationsService, V1.Services.AllocationsService>();
            builder
            .AddSingleton <V1.Interfaces.ITimePeriodsService, V1.Services.TimePeriodsService>();
            builder
            .AddSingleton <V1.Interfaces.IFundingStreamService, V1.Services.FundingStreamService>();

            // Register v2 services
            builder
            .AddSingleton <V2.Interfaces.IAllocationNotificationFeedsService, V2.Services.AllocationNotificationFeedsService>();
            builder
            .AddSingleton <V2.Interfaces.IProviderResultsService, V2.Services.ProviderResultsService>();
            builder
            .AddSingleton <V2.Interfaces.IAllocationsService, V2.Services.AllocationsService>();
            builder
            .AddSingleton <V2.Interfaces.ITimePeriodsService, V2.Services.TimePeriodsService>();
            builder
            .AddSingleton <V2.Interfaces.IFundingStreamService, V2.Services.FundingStreamService>();

            // Register dependencies
            builder
            .AddSingleton <IAllocationNotificationsFeedsSearchService, AllocationNotificationsFeedsSearchService>()
            .AddSingleton <IHealthChecker, AllocationNotificationsFeedsSearchService>();

            builder
            .AddSingleton <ICalculationResultsRepository, CalculationResultsRepository>();
            builder
            .AddSingleton <IPublishedResultsService, PublishedResultsService>()
            .AddSingleton <IHealthChecker, PublishedResultsService>();

            builder
            .AddSingleton <ICalculationProviderResultsSearchService, CalculationProviderResultsSearchService>()
            .AddSingleton <IHealthChecker, CalculationProviderResultsSearchService>();
            builder.AddSingleton <IProviderImportMappingService, ProviderImportMappingService>();

            builder
            .AddSingleton <IAllocationNotificationsFeedsSearchService, AllocationNotificationsFeedsSearchService>();

            MapperConfiguration resultsConfig = new MapperConfiguration(c =>
            {
                c.AddProfile <DatasetsMappingProfile>();
                c.AddProfile <ExternalApiMappingProfile>();
            });

            builder
            .AddSingleton(resultsConfig.CreateMapper());

            builder.AddSingleton <IVersionRepository <SpecificationVersion>, VersionRepository <SpecificationVersion> >((ctx) =>
            {
                CosmosDbSettings specsVersioningDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", specsVersioningDbSettings);

                specsVersioningDbSettings.CollectionName = "specs";

                CosmosRepository resultsRepostory = new CosmosRepository(specsVersioningDbSettings);

                return(new VersionRepository <SpecificationVersion>(resultsRepostory));
            });

            builder.AddSingleton <ICalculationResultsRepository, CalculationResultsRepository>((ctx) =>
            {
                CosmosDbSettings calssDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", calssDbSettings);

                calssDbSettings.CollectionName = "calculationresults";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(calssDbSettings);

                return(new CalculationResultsRepository(calcsCosmosRepostory));
            });

            builder.AddSingleton <IProviderSourceDatasetRepository, ProviderSourceDatasetRepository>((ctx) =>
            {
                CosmosDbSettings provDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", provDbSettings);

                provDbSettings.CollectionName = "providerdatasets";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(provDbSettings);

                return(new ProviderSourceDatasetRepository(calcsCosmosRepostory));
            });

            builder.AddSingleton <IPublishedProviderResultsRepository, PublishedProviderResultsRepository>((ctx) =>
            {
                CosmosDbSettings resultsDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", resultsDbSettings);

                resultsDbSettings.CollectionName = "publishedproviderresults";

                CosmosRepository resultsRepostory = new CosmosRepository(resultsDbSettings);

                return(new PublishedProviderResultsRepository(resultsRepostory));
            });

            builder.AddSingleton <IProviderChangesRepository, ProviderChangesRepository>((ctx) =>
            {
                CosmosDbSettings repoSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", repoSettings);

                repoSettings.CollectionName = "publishedproviderchanges";

                CosmosRepository repo = new CosmosRepository(repoSettings);

                ILogger logger = ctx.GetRequiredService <ILogger>();

                return(new ProviderChangesRepository(repo, logger));
            });

            builder
            .AddSingleton <ISpecificationsRepository, SpecificationsRepository>();

            builder
            .AddSingleton <IPublishedProviderResultsAssemblerService, PublishedProviderResultsAssemblerService>();

            builder.AddSingleton <Services.Specs.Interfaces.ISpecificationsRepository, Services.Specs.SpecificationsRepository>(
                ctx =>
            {
                CosmosDbSettings specRepoDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", specRepoDbSettings);

                specRepoDbSettings.CollectionName = "specs";

                CosmosRepository cosmosRepository = new CosmosRepository(specRepoDbSettings);

                return(new Services.Specs.SpecificationsRepository(cosmosRepository));
            });

            builder.AddSingleton <IVersionRepository <PublishedAllocationLineResultVersion>, VersionRepository <PublishedAllocationLineResultVersion> >((ctx) =>
            {
                CosmosDbSettings versioningDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", versioningDbSettings);

                versioningDbSettings.CollectionName = "publishedproviderresults";

                CosmosRepository resultsRepostory = new CosmosRepository(versioningDbSettings);

                return(new VersionRepository <PublishedAllocationLineResultVersion>(resultsRepostory));
            });

            builder.AddSingleton <IPublishedAllocationLineLogicalResultVersionService, PublishedAllocationLineLogicalResultVersionService>();

            builder.AddSingleton <IPublishedProviderResultsSettings, PublishedProviderResultsSettings>((ctx) =>
            {
                PublishedProviderResultsSettings settings = new PublishedProviderResultsSettings();

                Configuration.Bind("PublishedProviderResultsSettings", settings);

                return(settings);
            });

            builder.AddSingleton <IFundingService, FundingService>();
            builder.AddSingleton <IValidator <PolicyCreateModel>, PolicyCreateModelValidator>();
            builder.AddSingleton <IValidator <SpecificationCreateModel>, SpecificationCreateModelValidator>();
            builder.AddSingleton <IValidator <CalculationCreateModel>, CalculationCreateModelValidator>();
            builder.AddSingleton <IValidator <AssignDefinitionRelationshipMessage>, AssignDefinitionRelationshipMessageValidator>();
            builder.AddSingleton <IValidator <SpecificationEditModel>, SpecificationEditModelValidator>();
            builder.AddSingleton <IValidator <PolicyEditModel>, PolicyEditModelValidator>();
            builder.AddSingleton <IValidator <CalculationEditModel>, CalculationEditModelValidator>();
            builder.AddSingleton <IResultsRepository, ResultsRepository>();

            builder.AddResultsInterServiceClient(Configuration);

            builder.AddUserProviderFromRequest();

            builder.AddSearch(Configuration);

            builder.AddServiceBus(Configuration);

            builder.AddCaching(Configuration);

            builder.AddApplicationInsights(Configuration, "CalculateFunding.Api.External");
            builder.AddApplicationInsightsTelemetryClient(Configuration, "CalculateFunding.Api.External");
            builder.AddLogging("CalculateFunding.Api.External");
            builder.AddTelemetry();

            builder.AddSpecificationsInterServiceClient(Configuration);

            builder.AddPolicySettings(Configuration);

            builder.AddHttpContextAccessor();

            builder.AddJobsInterServiceClient(Configuration);

            builder.AddSingleton <IResultsResiliencePolicies>((ctx) =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                return(new ResiliencePolicies()
                {
                    CalculationProviderResultsSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                    ResultsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    ResultsSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                    SpecificationsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    AllocationNotificationFeedSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                    ProviderProfilingRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    PublishedProviderCalculationResultsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    PublishedProviderResultsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    JobsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    CalculationsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    ProviderCalculationResultsSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                    ProviderChangesRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    CsvBlobPolicy = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                });
            });
            builder.AddHealthCheckMiddleware();
            builder.AddTransient <ContentTypeCheckMiddleware>();

            ServiceProvider = builder.BuildServiceProvider();
        }
コード例 #24
0
ファイル: Startup.cs プロジェクト: melih154/CFS-Backend
        public void RegisterComponents(IServiceCollection builder)
        {
            builder.AddSingleton <ICalculationResultsRepository, CalculationResultsRepository>();
            builder
            .AddSingleton <IResultsService, ResultsService>()
            .AddSingleton <IHealthChecker, ResultsService>();
            builder
            .AddSingleton <IPublishedResultsService, PublishedResultsService>()
            .AddSingleton <IHealthChecker, PublishedResultsService>();
            builder
            .AddSingleton <IResultsSearchService, ResultsSearchService>()
            .AddSingleton <IHealthChecker, ResultsSearchService>();

            builder
            .AddSingleton <IProviderCalculationResultsSearchService, ProviderCalculationResultsSearchService>()
            .AddSingleton <IHealthChecker, ProviderCalculationResultsSearchService>();

            builder
            .AddSingleton <ICalculationProviderResultsSearchService, CalculationProviderResultsSearchService>()
            .AddSingleton <IHealthChecker, CalculationProviderResultsSearchService>();

            builder.AddSingleton <IProviderImportMappingService, ProviderImportMappingService>();

            builder
            .AddSingleton <IAllocationNotificationsFeedsSearchService, AllocationNotificationsFeedsSearchService>();

            builder.AddSingleton <IProviderVariationAssemblerService, ProviderVariationAssemblerService>();

            MapperConfiguration resultsConfig = new MapperConfiguration(c =>
            {
                c.AddProfile <DatasetsMappingProfile>();
                c.AddProfile <ResultServiceMappingProfile>();
            });

            builder
            .AddSingleton(resultsConfig.CreateMapper());

            builder.AddSingleton <ICalculationResultsRepository, CalculationResultsRepository>((ctx) =>
            {
                CosmosDbSettings calssDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", calssDbSettings);

                calssDbSettings.CollectionName = "calculationresults";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(calssDbSettings);

                return(new CalculationResultsRepository(calcsCosmosRepostory));
            });

            builder.AddSingleton <IProviderSourceDatasetRepository, ProviderSourceDatasetRepository>((ctx) =>
            {
                CosmosDbSettings provDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", provDbSettings);

                provDbSettings.CollectionName = "providerdatasets";

                CosmosRepository calcsCosmosRepostory = new CosmosRepository(provDbSettings);

                return(new ProviderSourceDatasetRepository(calcsCosmosRepostory));
            });

            builder.AddSingleton <IPublishedProviderResultsRepository, PublishedProviderResultsRepository>((ctx) =>
            {
                CosmosDbSettings resultsDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", resultsDbSettings);

                resultsDbSettings.CollectionName = "publishedproviderresults";

                CosmosRepository resultsRepostory = new CosmosRepository(resultsDbSettings);

                return(new PublishedProviderResultsRepository(resultsRepostory));
            });

            builder.AddSingleton <IProviderChangesRepository, ProviderChangesRepository>((ctx) =>
            {
                CosmosDbSettings resultsDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", resultsDbSettings);

                resultsDbSettings.CollectionName = "publishedproviderchanges";

                CosmosRepository resultsRepostory = new CosmosRepository(resultsDbSettings);

                ILogger logger = ctx.GetService <ILogger>();

                return(new ProviderChangesRepository(resultsRepostory, logger));
            });

            builder.AddSingleton <IProviderCalculationResultsReIndexerService, ProviderCalculationResultsReIndexerService>();

            builder.AddSingleton <IValidator <MasterProviderModel>, MasterProviderModelValidator>();

            builder
            .AddSingleton <ISpecificationsRepository, SpecificationsRepository>();

            builder
            .AddSingleton <ICalculationsRepository, CalculationsRepository>();

            builder
            .AddSingleton <IPublishedProviderResultsAssemblerService, PublishedProviderResultsAssemblerService>();

            builder.AddSingleton <IPublishedProviderResultsSettings, PublishedProviderResultsSettings>((ctx) =>
            {
                PublishedProviderResultsSettings settings = new PublishedProviderResultsSettings();

                Configuration.Bind("PublishedProviderResultsSettings", settings);

                return(settings);
            });

            builder.AddSingleton <IVersionRepository <PublishedAllocationLineResultVersion>, VersionRepository <PublishedAllocationLineResultVersion> >((ctx) =>
            {
                CosmosDbSettings versioningDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", versioningDbSettings);

                versioningDbSettings.CollectionName = "publishedproviderresults";

                CosmosRepository resultsRepostory = new CosmosRepository(versioningDbSettings);

                return(new VersionRepository <PublishedAllocationLineResultVersion>(resultsRepostory));
            });

            builder
            .AddSingleton <IBlobClient, BlobClient>((ctx) =>
            {
                AzureStorageSettings storageSettings = new AzureStorageSettings();

                Configuration.Bind("AzureStorageSettings", storageSettings);

                storageSettings.ContainerName = "datasets";

                return(new BlobClient(storageSettings));
            });

            builder.AddUserProviderFromRequest();

            builder.AddSearch(Configuration);

            builder.AddServiceBus(Configuration);

            builder.AddCaching(Configuration);

            builder.AddApplicationInsights(Configuration, "CalculateFunding.Api.Results");
            builder.AddApplicationInsightsTelemetryClient(Configuration, "CalculateFunding.Api.Results");
            builder.AddLogging("CalculateFunding.Api.Results");
            builder.AddTelemetry();

            builder.AddSpecificationsInterServiceClient(Configuration);
            builder.AddCalcsInterServiceClient(Configuration);
            builder.AddJobsInterServiceClient(Configuration);

            builder.AddPolicySettings(Configuration);

            builder.AddHttpContextAccessor();

            builder.AddFeatureToggling(Configuration);

            builder.AddSingleton <IPublishedAllocationLineLogicalResultVersionService, PublishedAllocationLineLogicalResultVersionService>();

            builder.AddSingleton <IResultsResiliencePolicies>((ctx) =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                return(new ResiliencePolicies()
                {
                    CalculationProviderResultsSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                    ResultsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    ResultsSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                    SpecificationsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    AllocationNotificationFeedSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                    ProviderProfilingRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    PublishedProviderCalculationResultsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    PublishedProviderResultsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    CalculationsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    JobsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    ProviderChangesRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    ProviderCalculationResultsSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy),
                    CsvBlobPolicy = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                });
            });

            builder.AddApiKeyMiddlewareSettings((IConfigurationRoot)Configuration);

            builder.AddHealthCheckMiddleware();

            ServiceProvider = builder.BuildServiceProvider();
        }
コード例 #25
0
        private static async Task SendData(string databaseId, string containerId, CancellationToken externalCancellationToken, IProgress <Progress> progress, int maxParallelization, int sendNotificationAfter, bool isTweets = false)
        {
            // Place Cosmos DB calls into bulkhead to prevent thread starvation caused by failing or waiting calls.
            // Let any number (int.MaxValue) of calls _queue for an execution slot in the bulkhead to allow the generator to send as many calls as possible.
            BulkheadPolicy BulkheadForCosmosDbCalls = Policy.BulkheadAsync(maxParallelization, int.MaxValue);

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

            // Perform garbage collection prior to timing for statistics.
            GC.Collect();
            GC.WaitForPendingFinalizers();

            var internalCancellationTokenSource = new CancellationTokenSource();
            var combinedToken = CancellationTokenSource.CreateLinkedTokenSource(externalCancellationToken, internalCancellationTokenSource.Token).Token;
            var tasks         = new List <Task>();
            var messages      = new ConcurrentQueue <ColoredMessage>();
            var cosmosTimer   = new Stopwatch();

            // Create the Cosmos DB collection URI:
            var collectionUri = UriFactory.CreateDocumentCollectionUri(databaseId, containerId);

            // Ensure none of what follows runs synchronously.
            await Task.FromResult(true).ConfigureAwait(false);

            // Continue while cancellation is not requested.
            while (!combinedToken.IsCancellationRequested)
            {
                if (externalCancellationToken.IsCancellationRequested)
                {
                    return;
                }

                for (int i = 0; i <= 4; i++)
                {
                    _totalMessages++;
                    var thisRequest = _totalMessages;

                    #region Write to Cosmos DB

                    _cosmosRequestsMade++;
                    tasks.Add(BulkheadForCosmosDbCalls.ExecuteAsync(async ct =>
                    {
                        try
                        {
                            cosmosTimer.Start();

                            ResourceResponse <Document> response = null;

                            // Send to Cosmos DB:
                            if (isTweets)
                            {
                                response = await _cosmosDbClient
                                           .CreateDocumentAsync(collectionUri, TweetGenerator.Generate())
                                           .ConfigureAwait(false);
                            }
                            else
                            {
                                response = await _cosmosDbClient
                                           .CreateDocumentAsync(collectionUri, TelemetryGenerator.Generate())
                                           .ConfigureAwait(false);
                            }


                            cosmosTimer.Stop();
                            _cosmosElapsedTime = cosmosTimer.ElapsedMilliseconds;

                            // Keep running total of RUs consumed:
                            _cosmosRUsPerBatch += response.RequestCharge;

                            _cosmosRequestsSucceededInBatch++;
                        }
                        catch (DocumentClientException de)
                        {
                            if (!ct.IsCancellationRequested)
                            {
                                messages.Enqueue(new ColoredMessage($"Cosmos DB request {thisRequest} eventually failed with: {de.Message}; Retry-after: {de.RetryAfter.TotalSeconds} seconds.", Color.Red));
                            }

                            _cosmosRequestsFailed++;
                        }
                        catch (Exception e)
                        {
                            if (!ct.IsCancellationRequested)
                            {
                                messages.Enqueue(new ColoredMessage($"Cosmos DB request {thisRequest} eventually failed with: {e.Message}", Color.Red));
                            }

                            _cosmosRequestsFailed++;
                        }
                    }, combinedToken)
                              .ContinueWith((t, k) =>
                    {
                        if (t.IsFaulted)
                        {
                            messages.Enqueue(new ColoredMessage($"Request to Cosmos DB failed with: {t.Exception?.Flatten().InnerExceptions.First().Message}", Color.Red));
                        }

                        _cosmosRequestsFailed++;
                    }, thisRequest, TaskContinuationOptions.NotOnRanToCompletion)
                              );

                    #endregion Write to Cosmos DB

                    if (i == 4 && isTweets)
                    {
                        var span = TimeSpan.FromMilliseconds(2000);
                        await Task.Delay(span, externalCancellationToken);
                    }
                }

                if (_totalMessages % sendNotificationAfter == 0)
                {
                    cosmosTimer.Stop();
                    _cosmosTotalElapsedTime  += _cosmosElapsedTime;
                    _cosmosRequestsSucceeded += _cosmosRequestsSucceededInBatch;

                    // Calculate RUs/second/month:
                    var ruPerSecond = (_cosmosRUsPerBatch / (_cosmosElapsedTime * .001));
                    var ruPerMonth  = ruPerSecond * 86400 * 30;

                    if (!isTweets)
                    {
                        // Add delay every 500 messages that are sent.
                        await Task.Delay(5000, externalCancellationToken);
                    }

                    // Output statistics. Be on the lookout for the following:
                    //  - Inserted line shows successful inserts in this batch and throughput for writes/second with RU/s usage and estimated monthly ingestion rate added to Cosmos DB statistics.
                    //  - Processing time: Processing time for the past 1,000 requested inserts.
                    //  - Total elapsed time: Running total of time taken to process all documents.
                    //  - Succeeded shows number of accumulative successful inserts to the service.
                    //  - Pending are items in the bulkhead queue. This amount will continue to grow if the service is unable to keep up with demand.
                    //  - Accumulative failed requests that encountered an exception.
                    messages.Enqueue(new ColoredMessage($"Total requests: requested {_totalMessages:00} ", Color.Cyan));
                    messages.Enqueue(new ColoredMessage(string.Empty));
                    messages.Enqueue(new ColoredMessage($"Inserted {_cosmosRequestsSucceededInBatch:00} docs @ {(_cosmosRequestsSucceededInBatch / (_cosmosElapsedTime * .001)):0.00} writes/s, {ruPerSecond:0.00} RU/s ({(ruPerMonth / (1000 * 1000 * 1000)):0.00}B max monthly 1KB writes) ", Color.White));
                    messages.Enqueue(new ColoredMessage($"Processing time {_cosmosElapsedTime} ms", Color.Magenta));
                    messages.Enqueue(new ColoredMessage($"Total elapsed time {(_cosmosTotalElapsedTime * .001):0.00} seconds", Color.Magenta));
                    messages.Enqueue(new ColoredMessage($"Total succeeded {_cosmosRequestsSucceeded:00} ", Color.Green));
                    messages.Enqueue(new ColoredMessage($"Total pending {_cosmosRequestsMade - _cosmosRequestsSucceeded - _cosmosRequestsFailed:00} ", Color.Yellow));
                    messages.Enqueue(new ColoredMessage($"Total failed {_cosmosRequestsFailed:00}", Color.Red));
                    messages.Enqueue(new ColoredMessage(string.Empty));

                    // Restart timers and reset batch settings:
                    cosmosTimer.Restart();
                    _cosmosElapsedTime = 0;
                    _cosmosRUsPerBatch = 0;
                    _cosmosRequestsSucceededInBatch = 0;

                    // Output all messages available right now, in one go.
                    progress.Report(ProgressWithMessages(ConsumeAsEnumerable(messages)));
                }
            }

            messages.Enqueue(new ColoredMessage("Data generation complete", Color.Magenta));
            progress.Report(ProgressWithMessages(ConsumeAsEnumerable(messages)));

            BulkheadForCosmosDbCalls.Dispose();
            cosmosTimer.Stop();
        }
コード例 #26
0
        private static IServiceProvider Register(IServiceCollection builder, IConfigurationRoot config)
        {
            builder.AddSingleton <OnDataDefinitionChanges>();
            builder.AddSingleton <OnEditCaluclationEvent>();
            builder.AddSingleton <OnEditSpecificationEvent>();
            builder.AddSingleton <IScenariosRepository, ScenariosRepository>();
            builder.AddSingleton <IScenariosService, ScenariosService>();
            builder.AddSingleton <IScenariosSearchService, ScenariosSearchService>();
            builder
            .AddSingleton <IValidator <CreateNewTestScenarioVersion>, CreateNewTestScenarioVersionValidator>();
            builder
            .AddSingleton <ISpecificationsRepository, SpecificationsRepository>();

            builder
            .AddSingleton <IBuildProjectRepository, BuildProjectRepository>();

            builder
            .AddSingleton <ICalcsRepository, CalcsRepository>();

            builder
            .AddSingleton <ICancellationTokenProvider, InactiveCancellationTokenProvider>();

            builder
            .AddSingleton <IDatasetRepository, DatasetRepository>();

            builder
            .AddSingleton <IDatasetDefinitionFieldChangesProcessor, DatasetDefinitionFieldChangesProcessor>();

            builder.AddSingleton <IVersionRepository <TestScenarioVersion>, VersionRepository <TestScenarioVersion> >((ctx) =>
            {
                CosmosDbSettings scenariosVersioningDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", scenariosVersioningDbSettings);

                scenariosVersioningDbSettings.CollectionName = "tests";

                CosmosRepository resultsRepostory = new CosmosRepository(scenariosVersioningDbSettings);

                return(new VersionRepository <TestScenarioVersion>(resultsRepostory));
            });

            builder.AddCalcsInterServiceClient(config);
            builder.AddSpecificationsInterServiceClient(config);
            builder.AddDatasetsInterServiceClient(config);

            if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
            {
                builder.AddCosmosDb(config, "tests");
            }
            else
            {
                builder.AddCosmosDb(config);
            }

            builder.AddJobsInterServiceClient(config);

            builder.AddSearch(config);

            builder.AddServiceBus(config);

            builder.AddCaching(config);

            builder.AddApplicationInsights(config, "CalculateFunding.Functions.Scenarios");
            builder.AddApplicationInsightsTelemetryClient(config, "CalculateFunding.Functions.Scenarios");

            builder.AddLogging("CalculateFunding.Functions.Scenarios");

            builder.AddTelemetry();

            builder.AddFeatureToggling(config);

            builder.AddPolicySettings(config);

            builder.AddSingleton <IScenariosResiliencePolicies>((ctx) =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                Policy redisPolicy = ResiliencePolicyHelpers.GenerateRedisPolicy(totalNetworkRequestsPolicy);

                return(new ScenariosResiliencePolicies()
                {
                    CalcsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    JobsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    DatasetRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    ScenariosRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy)
                });
            });

            return(builder.BuildServiceProvider());
        }
コード例 #27
0
        private static IServiceProvider Register(IServiceCollection builder, IConfigurationRoot config)
        {
            builder.AddSingleton <OnCosmosDbDiagnosticsReceived>();

            builder.AddSingleton <OnScaleUpCosmosDbCollection>();

            builder.AddSingleton <OnIncrementalScaleDownCosmosDbCollection>();

            builder.AddSingleton <OnScaleDownCosmosDbCollection>();

            builder.AddSingleton <ICosmosDbScalingRepositoryProvider, CosmosDbScalingRepositoryProvider>();

            builder.AddSingleton <ICosmosDbScalingService, CosmosDbScalingService>();

            builder.AddSingleton <ICosmosDbScalingRequestModelBuilder, CosmosDbScalingRequestModelBuilder>();

            builder.AddSingleton <ICosmosDbThrottledEventsFilter, CosmosDbThrottledEventsFilter>();

            builder.AddSingleton <CalculationProviderResultsScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "calculationresults";

                CosmosRepository cosmosRepostory = new CosmosRepository(cosmosDbSettings);

                return(new CalculationProviderResultsScalingRepository(cosmosRepostory));
            });

            builder.AddSingleton <ProviderSourceDatasetsScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "providerdatasets";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new ProviderSourceDatasetsScalingRepository(cosmosRepository));
            });

            builder.AddSingleton <CalculationsScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "calcs";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new CalculationsScalingRepository(cosmosRepository));
            });

            builder.AddSingleton <JobsScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "jobs";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new JobsScalingRepository(cosmosRepository));
            });

            builder.AddSingleton <DatasetAggregationsScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "datasetaggregations";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new DatasetAggregationsScalingRepository(cosmosRepository));
            });

            builder.AddSingleton <DatasetsScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "datasets";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new DatasetsScalingRepository(cosmosRepository));
            });

            builder.AddSingleton <ProfilingScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "profiling";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new ProfilingScalingRepository(cosmosRepository));
            });

            builder.AddSingleton <SpecificationsScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "specs";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new SpecificationsScalingRepository(cosmosRepository));
            });

            builder.AddSingleton <TestResultsScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "testresults";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new TestResultsScalingRepository(cosmosRepository));
            });

            builder.AddSingleton <TestsScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "tests";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new TestsScalingRepository(cosmosRepository));
            });

            builder.AddSingleton <UsersScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "users";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new UsersScalingRepository(cosmosRepository));
            });

            builder.AddSingleton <PublishedProviderResultsScalingRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "publishedproviderresults";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new PublishedProviderResultsScalingRepository(cosmosRepository));
            });

            builder.AddSingleton <ICosmosDbScalingConfigRepository>((ctx) =>
            {
                CosmosDbSettings cosmosDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", cosmosDbSettings);

                cosmosDbSettings.CollectionName = "cosmosscalingconfig";

                CosmosRepository cosmosRepository = new CosmosRepository(cosmosDbSettings);

                return(new CosmosDbScalingConfigRepository(cosmosRepository));
            });

            builder.AddCaching(config);

            builder.AddJobsInterServiceClient(config);

            builder.AddServiceBus(config);

            builder.AddApplicationInsightsTelemetryClient(config, "CalculateFunding.Functions.CosmosDbScaling");

            builder.AddLogging("CalculateFunding.Functions.CosmosDbScaling", config);

            builder.AddTelemetry();

            builder.AddFeatureToggling(config);

            builder.AddSingleton <ICosmosDbScallingResilliencePolicies>(m =>
            {
                PolicySettings policySettings = builder.GetPolicySettings(config);

                BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                CosmosDbScallingResilliencePolicies resiliencePolicies = new CosmosDbScallingResilliencePolicies()
                {
                    ScalingRepository       = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    ScalingConfigRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    JobsApiClient           = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    CacheProvider           = ResiliencePolicyHelpers.GenerateRedisPolicy(totalNetworkRequestsPolicy)
                };

                return(resiliencePolicies);
            });

            return(builder.BuildServiceProvider());
        }
コード例 #28
0
ファイル: Startup.cs プロジェクト: melih154/CFS-Backend
        private static IServiceProvider Register(IServiceCollection builder, IConfigurationRoot config)
        {
            builder
            .AddSingleton <OnTestSpecificationProviderResultsCleanup>();

            builder
            .AddSingleton <OnEditSpecificationEvent>();

            builder
            .AddSingleton <OnTestExecution>();

            builder
            .AddSingleton <IBuildProjectRepository, BuildProjectRepository>();

            builder
            .AddSingleton <IGherkinParserService, GherkinParserService>();

            builder
            .AddSingleton <IGherkinParser, GherkinParser>();

            builder
            .AddSingleton <ICodeMetadataGeneratorService, ReflectionCodeMetadataGenerator>();

            builder
            .AddSingleton <IStepParserFactory, StepParserFactory>();

            builder
            .AddSingleton <ITestResultsRepository, TestResultsRepository>();

            builder
            .AddSingleton <ISpecificationRepository, SpecificationRepository>();

            builder
            .AddSingleton <IScenariosRepository, ScenariosRepository>();

            builder
            .AddSingleton <ITestEngineService, Services.TestRunner.Services.TestEngineService>();

            builder
            .AddSingleton <ITestEngine, Services.TestRunner.TestEngine>();

            builder
            .AddSingleton <IGherkinExecutor, GherkinExecutor>();

            builder
            .AddSingleton <ICalculationsRepository, CalculationsRepository>();

            builder.AddSingleton <IProviderService, ProviderService>();

            builder.AddSingleton <ICosmosRepository, CosmosRepository>();

            builder.AddSingleton <IProviderSourceDatasetsRepository, ProviderSourceDatasetsRepository>((ctx) =>
            {
                CosmosDbSettings providersDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", providersDbSettings);

                providersDbSettings.CollectionName = "providerdatasets";

                CosmosRepository providersCosmosRepostory = new CosmosRepository(providersDbSettings);

                EngineSettings engineSettings = ctx.GetService <EngineSettings>();

                return(new ProviderSourceDatasetsRepository(providersCosmosRepostory, engineSettings));
            });

            builder.AddSingleton <IProviderResultsRepository, ProviderResultsRepository>((ctx) =>
            {
                CosmosDbSettings providersDbSettings = new CosmosDbSettings();

                config.Bind("CosmosDbSettings", providersDbSettings);

                providersDbSettings.CollectionName = "calculationresults";

                CosmosRepository providersCosmosRepostory = new CosmosRepository(providersDbSettings);

                ICacheProvider cacheProvider = ctx.GetService <ICacheProvider>();

                return(new ProviderResultsRepository(providersCosmosRepostory));
            });

            builder.AddSingleton <ITestResultsSearchService, TestResultsSearchService>();

            builder.AddSingleton <ITestResultsCountsService, TestResultsCountsService>();

            MapperConfiguration resultsMappingConfiguration = new MapperConfiguration(c =>
            {
                c.AddProfile <ResultsMappingProfile>();
                c.AddProfile <ProviderMappingProfile>();
            });

            builder
            .AddSingleton(resultsMappingConfiguration.CreateMapper());

            builder.AddSingleton <ITestResultsService, TestResultsService>();

            if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development")
            {
                builder.AddCosmosDb(config, "testresults");
            }
            else
            {
                builder.AddCosmosDb(config);
            }

            builder.AddSearch(config);

            builder.AddSpecificationsInterServiceClient(config);
            builder.AddScenariosInterServiceClient(config);
            builder.AddCalcsInterServiceClient(config);
            builder.AddResultsInterServiceClient(config);

            builder.AddCaching(config);

            builder.AddApplicationInsights(config, "CalculateFunding.Functions.TestEngine");
            builder.AddApplicationInsightsTelemetryClient(config, "CalculateFunding.Functions.TestEngine", TelemetryChannelType.Sync);
            builder.AddLogging("CalculateFunding.Functions.TestEngine");

            builder.AddTelemetry();

            builder.AddEngineSettings(config);

            builder.AddPolicySettings(config);

            builder.AddFeatureToggling(config);

            builder.AddSingleton <ITestRunnerResiliencePolicies>((ctx) =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                Policy redisPolicy = ResiliencePolicyHelpers.GenerateRedisPolicy(totalNetworkRequestsPolicy);

                ResiliencePolicies resiliencePolicies = new ResiliencePolicies()
                {
                    BuildProjectRepository           = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    CacheProviderRepository          = redisPolicy,
                    ProviderResultsRepository        = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    ProviderSourceDatasetsRepository = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    ScenariosRepository         = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(new[] { totalNetworkRequestsPolicy, redisPolicy }),
                    SpecificationRepository     = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    TestResultsRepository       = CosmosResiliencePolicyHelper.GenerateCosmosPolicy(totalNetworkRequestsPolicy),
                    TestResultsSearchRepository = SearchResiliencePolicyHelper.GenerateSearchPolicy(totalNetworkRequestsPolicy)
                };

                return(resiliencePolicies);
            });

            return(builder.BuildServiceProvider());
        }
コード例 #29
0
ファイル: Startup.cs プロジェクト: melih154/CFS-Backend
        public void RegisterComponents(IServiceCollection builder)
        {
            builder.AddSingleton <IScenariosRepository, ScenariosRepository>();
            builder
            .AddSingleton <IScenariosService, ScenariosService>()
            .AddSingleton <IHealthChecker, ScenariosService>();
            builder
            .AddSingleton <IScenariosSearchService, ScenariosSearchService>()
            .AddSingleton <IHealthChecker, ScenariosSearchService>();

            builder
            .AddSingleton <IValidator <CreateNewTestScenarioVersion>, CreateNewTestScenarioVersionValidator>();
            builder
            .AddSingleton <ISpecificationsRepository, SpecificationsRepository>();

            builder
            .AddSingleton <IBuildProjectRepository, BuildProjectRepository>();

            builder
            .AddSingleton <IDatasetDefinitionFieldChangesProcessor, DatasetDefinitionFieldChangesProcessor>();

            builder.AddSingleton <IVersionRepository <TestScenarioVersion>, VersionRepository <TestScenarioVersion> >((ctx) =>
            {
                CosmosDbSettings scenariosVersioningDbSettings = new CosmosDbSettings();

                Configuration.Bind("CosmosDbSettings", scenariosVersioningDbSettings);

                scenariosVersioningDbSettings.CollectionName = "tests";

                CosmosRepository resultsRepostory = new CosmosRepository(scenariosVersioningDbSettings);

                return(new VersionRepository <TestScenarioVersion>(resultsRepostory));
            });

            builder
            .AddSingleton <ICalcsRepository, CalcsRepository>();

            builder
            .AddSingleton <ICancellationTokenProvider, HttpContextCancellationProvider>();

            builder.AddSingleton <IDatasetRepository, DatasetRepository>();

            builder
            .AddSingleton <IDatasetDefinitionFieldChangesProcessor, DatasetDefinitionFieldChangesProcessor>();

            builder.AddUserProviderFromRequest();

            builder.AddCalcsInterServiceClient(Configuration);
            builder.AddSpecificationsInterServiceClient(Configuration);
            builder.AddDatasetsInterServiceClient(Configuration);
            builder.AddJobsInterServiceClient(Configuration);

            builder.AddCosmosDb(Configuration);

            builder.AddSearch(Configuration);

            builder.AddServiceBus(Configuration);

            builder.AddCaching(Configuration);

            builder.AddFeatureToggling(Configuration);

            builder.AddApplicationInsights(Configuration, "CalculateFunding.Api.Scenarios");
            builder.AddApplicationInsightsTelemetryClient(Configuration, "CalculateFunding.Api.Scenarios");
            builder.AddLogging("CalculateFunding.Api.Scenarios");
            builder.AddTelemetry();

            builder.AddApiKeyMiddlewareSettings((IConfigurationRoot)Configuration);

            builder.AddHttpContextAccessor();

            builder.AddHealthCheckMiddleware();

            builder.AddPolicySettings(Configuration);

            builder.AddSingleton <IScenariosResiliencePolicies>((ctx) =>
            {
                PolicySettings policySettings = ctx.GetService <PolicySettings>();

                BulkheadPolicy totalNetworkRequestsPolicy = ResiliencePolicyHelpers.GenerateTotalNetworkRequestsPolicy(policySettings);

                Policy redisPolicy = ResiliencePolicyHelpers.GenerateRedisPolicy(totalNetworkRequestsPolicy);

                return(new ScenariosResiliencePolicies()
                {
                    CalcsRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    JobsApiClient = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy),
                    DatasetRepository = ResiliencePolicyHelpers.GenerateRestRepositoryPolicy(totalNetworkRequestsPolicy)
                });
            });
        }
コード例 #30
0
        public override async Task ExecuteAsync(CancellationToken externalCancellationToken, IProgress <DemoProgress> progress)
        {
            if (externalCancellationToken == null)
            {
                throw new ArgumentNullException(nameof(externalCancellationToken));
            }
            if (progress == null)
            {
                throw new ArgumentNullException(nameof(progress));
            }

            progress.Report(ProgressWithMessage(typeof(BulkheadAsyncDemo01_WithBulkheads).Name));
            progress.Report(ProgressWithMessage("======"));
            progress.Report(ProgressWithMessage(String.Empty));

            // Let's imagine this caller has some theoretically limited capacity.
            const int callerParallelCapacity = 8; // (artificially low - but easier to follow, to illustrate principle)

            BulkheadPolicy bulkheadForGoodCalls     = Policy.BulkheadAsync(callerParallelCapacity / 2, 10);
            BulkheadPolicy bulkheadForFaultingCalls = Policy.BulkheadAsync(callerParallelCapacity - callerParallelCapacity / 2, 10); // In this demo we let any number (int.MaxValue) of calls _queue for an execution slot in the bulkhead (simulating a system still _trying to accept/process as many of the calls as possible).  A subsequent demo will look at using no queue (and bulkhead rejections) to simulate automated horizontal scaling.

            var rand = new Random();

            totalRequests = 0;

            await Task.FromResult(true).ConfigureAwait(false); // Ensure none of what follows runs synchronously.

            IList <Task>            tasks = new List <Task>();
            CancellationTokenSource internalCancellationTokenSource = new CancellationTokenSource();
            CancellationToken       combinedToken = CancellationTokenSource.CreateLinkedTokenSource(externalCancellationToken, internalCancellationTokenSource.Token).Token;

            ConcurrentQueue <ColoredMessage> messages = new ConcurrentQueue <ColoredMessage>();

            using (var client = new HttpClient())
            {
                bool internalCancel = false;
                while (!internalCancel && !externalCancellationToken.IsCancellationRequested)
                {
                    totalRequests++;

                    int thisRequest = totalRequests;

                    // Randomly make either 'good' or 'faulting' calls.
                    if (rand.Next(0, 2) == 0)
                    {
                        goodRequestsMade++;
                        // Call 'good' endpoint.
                        tasks.Add(bulkheadForGoodCalls.ExecuteAsync(async ct =>
                        {
                            try
                            {
                                // Make a request and get a response, from the good endpoint
                                string msg = await(await client.GetAsync(Configuration.WEB_API_ROOT + "/api/nonthrottledgood/" + totalRequests, ct).ConfigureAwait(false)).Content.ReadAsStringAsync().ConfigureAwait(false);
                                if (!ct.IsCancellationRequested)
                                {
                                    messages.Enqueue(new ColoredMessage($"Response: {msg}", Color.Green));
                                }

                                goodRequestsSucceeded++;
                            }
                            catch (Exception e)
                            {
                                if (!ct.IsCancellationRequested)
                                {
                                    messages.Enqueue(new ColoredMessage($"Request {thisRequest} eventually failed with: {e.Message}", Color.Red));
                                }

                                goodRequestsFailed++;
                            }
                        }, combinedToken)
                                  .ContinueWith((t, k) =>
                        {
                            if (t.IsFaulted)
                            {
                                messages.Enqueue(new ColoredMessage($"Request {k} failed with: {t.Exception.Flatten().InnerExceptions.First().Message}", Color.Red));
                            }

                            goodRequestsFailed++;
                        }, thisRequest, TaskContinuationOptions.NotOnRanToCompletion)
                                  );
                    }
                    else
                    {
                        faultingRequestsMade++;
                        // call 'faulting' endpoint.
                        tasks.Add(bulkheadForFaultingCalls.ExecuteAsync(async ct =>
                        {
                            try
                            {
                                // Make a request and get a response, from the faulting endpoint
                                string msg = await(await client.GetAsync(Configuration.WEB_API_ROOT + "/api/nonthrottledfaulting/" + totalRequests, ct).ConfigureAwait(false)).Content.ReadAsStringAsync().ConfigureAwait(false);
                                if (!combinedToken.IsCancellationRequested)
                                {
                                    messages.Enqueue(new ColoredMessage($"Response: {msg}", Color.Green));
                                }

                                faultingRequestsSucceeded++;
                            }
                            catch (Exception e)
                            {
                                if (!ct.IsCancellationRequested)
                                {
                                    messages.Enqueue(new ColoredMessage($"Request {thisRequest} eventually failed with: {e.Message}", Color.Red));
                                }

                                faultingRequestsFailed++;
                            }
                        }, combinedToken)
                                  .ContinueWith((t, k) =>
                        {
                            if (t.IsFaulted)
                            {
                                messages.Enqueue(new ColoredMessage($"Request {k} failed with: {t.Exception.Flatten().InnerExceptions.First().Message}", Color.Red));
                            }

                            faultingRequestsFailed++;
                        }, thisRequest, TaskContinuationOptions.NotOnRanToCompletion)
                                  );
                    }

                    messages.Enqueue(new ColoredMessage($"Total requests: requested {totalRequests:00}, ", Color.White));
                    messages.Enqueue(new ColoredMessage($"Good endpoint: requested {goodRequestsMade:00}, ", Color.White));
                    messages.Enqueue(new ColoredMessage($"Good endpoint:succeeded {goodRequestsSucceeded:00}, ", Color.Green));
                    messages.Enqueue(new ColoredMessage($"Good endpoint:pending {goodRequestsMade - goodRequestsSucceeded - goodRequestsFailed:00}, ", Color.Yellow));
                    messages.Enqueue(new ColoredMessage($"Good endpoint:failed {goodRequestsFailed:00}.", Color.Red));

                    messages.Enqueue(new ColoredMessage(String.Empty));
                    messages.Enqueue(new ColoredMessage($"Faulting endpoint: requested {faultingRequestsMade:00}, ", Color.White));
                    messages.Enqueue(new ColoredMessage($"Faulting endpoint:succeeded {faultingRequestsSucceeded:00}, ", Color.Green));
                    messages.Enqueue(new ColoredMessage($"Faulting endpoint:pending {faultingRequestsMade - faultingRequestsSucceeded - faultingRequestsFailed:00}, ", Color.Yellow));
                    messages.Enqueue(new ColoredMessage($"Faulting endpoint:failed {faultingRequestsFailed:00}.", Color.Red));
                    messages.Enqueue(new ColoredMessage(String.Empty));

                    // Output all messages available right now, in one go.
                    progress.Report(ProgressWithMessages(ConsumeAsEnumerable(messages)));

                    // Wait briefly
                    await Task.Delay(TimeSpan.FromSeconds(0.2), externalCancellationToken).ConfigureAwait(false);

                    // Support cancellation by keyboard, when called from a console; ignore exceptions, if console not accessible.
                    try
                    {
                        internalCancel = Console.KeyAvailable;
                    }
                    catch { }
                }
            }

            bulkheadForFaultingCalls.Dispose();
            bulkheadForGoodCalls.Dispose();
        }