private IObservable <IEnumerable <PushResponse> > GenerateObservableForMakingIncrementingRequests( IRunSpecification runSpec, CancellationToken token) { var httpGateway = _httpGatewayProvider.Generate(runSpec); return(Observable.Interval(PerSecondSpan) // Derive the incrementing (capped) request count from current interval .Select(currentInterval => new { RequestCount = GetCappedRequestCount((int)currentInterval, runSpec.StartingRequestCount, runSpec.MaxRequestCount), Interval = (int)currentInterval }) // Pipeline request count and current interval into making requests .SelectMany( async requestInfo => await httpGateway.MakeStaggeredRequests(runSpec, requestInfo.RequestCount, requestInfo.Interval, token) .ConfigureAwait(false)) // Take interval sequence for specified number of seconds .Take(runSpec.NumberOfSeconds)); }
public async Task <IEnumerable <PushResponse> > MakeStaggeredRequests(IRunSpecification runSpec, int requestCount, int requestGrouping, CancellationToken token) { var delayTasks = new List <Task <PushResponse> >(); for (var count = 0; count < requestCount; count++) { var delay = random.Next(1, 1000); delayTasks.Add(GetDelayedAsync(runSpec.GenerateRelativeUrl(), "GET", null, delay, count, CancellationToken.None)); } return(await Task.WhenAll(delayTasks).ConfigureAwait(false)); }
public async Task <IEnumerable <PushResponse> > MakeStaggeredRequests( IRunSpecification runSpec, int requestCount, int requestGrouping, CancellationToken token) { // Fire off request tasks with staggered delay of 1-999 milliseconds var requestTasks = Enumerable.Range(1, requestCount) .Select(i => GetDelayedAsync( runSpec.GenerateRelativeUrl(), runSpec.Verb, runSpec.Content, random.Next(1, 1000), requestGrouping, token)) .ToList(); return(await Task.WhenAll(requestTasks) .ConfigureAwait(continueOnCapturedContext: false)); }
public async Task PushLoadAsync(IRunSpecification runSpec, CancellationToken token) { _logger.LogStarted(runSpec.NumberOfSeconds, runSpec.StartingRequestCount, runSpec.MaxRequestCount, runSpec.BaseUrl, string.Join(",", runSpec.DefaultRequestHeaders)); // Use the rx observable to make incrementing number of requests (per second) and compose responses var observableInterval = GenerateObservableForMakingIncrementingRequests(runSpec, token); await observableInterval .ForEachAsync(responses => { // Fold responses to get summaries var groupSummary = responses.Aggregate( new { Group = 0, TotalCount = 0, SuccessCount = 0, TotalTimeTakenMilliseconds = 0 }, (summary, response) => new { Group = response.RequestGrouping, TotalCount = summary.TotalCount + 1, SuccessCount = summary.SuccessCount + (response.IsSuccessful ? 1 : 0), TotalTimeTakenMilliseconds = summary.TotalTimeTakenMilliseconds + response.TimeTakenMilliseconds }); _logger.LogRequestGroupingSummary( groupSummary.Group, groupSummary.SuccessCount, groupSummary.TotalCount, groupSummary.TotalTimeTakenMilliseconds / groupSummary.TotalCount); }, token) .ConfigureAwait(false); _logger.LogFinished(); }
public IHttpGateway Generate(IRunSpecification runSpec) { return(new HttpGateway(_logger, runSpec.BaseUrl, runSpec.RequestTimeout, runSpec.DefaultRequestHeaders)); }