public Task Observe <TRequest, TResponse>(RequestHandlerExperiment <TRequest, TResponse> experiment) where TRequest : IRequest <TResponse> { Console.WriteLine($"baseline result: {experiment.BaselineExecution.Task.Result}"); var experimentExecution = experiment.ExperimentalExecutions.Single(); var message = experimentExecution.Task.IsCompletedSuccessfully ? $"experiment response: {experimentExecution.Task.Result}" : $"experiment error: {experimentExecution.Task.Exception.Message}"; Console.WriteLine(message); return(Task.CompletedTask); }
public async Task <TResponse> Execute <TRequest, TResponse>(List <IRequestHandler <TRequest, TResponse> > handlers, RequestPipelineContext <TRequest> context) where TRequest : IRequest <TResponse> { if (handlers.Count <= 1) { return(await DefaultRequestHandlerExecutionStrategy.Instance.Execute(handlers, context).ConfigureAwait()); } var baselineHandler = GetBaselineHandler(handlers); var toggle = context.ServiceProvider.GetRequiredService <IRequestHandlerExperimentToggle>(); var request = context.Request; var cancellationToken = context.CancellationToken; if (!await toggle.IsEnabled <TRequest, TResponse>(_experimentInfo, context).ConfigureAwait()) { return(await baselineHandler.Handle(request, cancellationToken).ConfigureAwait()); } var observer = context.ServiceProvider.GetRequiredService <IRequestHandlerExperimentObserver>(); var tasks = handlers.Select(handler => Execute(handler, request, cancellationToken)).ToListOptimized(); var executions = await Task.WhenAll(tasks).ConfigureAwait(); var baselineExecution = executions.Single(x => x.Handler == baselineHandler); var experimentExecutions = executions.Where(x => x != baselineExecution).ToList(); var experiment = new RequestHandlerExperiment <TRequest, TResponse> { BaselineExecution = baselineExecution, CancellationToken = cancellationToken, ExperimentalExecutions = experimentExecutions, Request = request }; await observer.Observe(experiment).ConfigureAwait(); return(await baselineExecution.Task.ConfigureAwait()); }