/// <summary> /// Constructor that validates the query request and initializes internal state and fixes/cleans up the individual queries /// </summary> public BatchResponseAggregator(BatchQueryRequest request) { if (request == null) { throw new ArgumentNullException("request"); } if (request.Queries == null || request.Queries.Count == 0) { throw new ArgumentException("No queries provided", "request"); } foreach (var counterRequest in request.Queries) { if (string.IsNullOrEmpty(counterRequest.UserContext)) { counterRequest.UserContext = Guid.NewGuid().ToString("D"); } else if (this.requestMapping.ContainsKey(counterRequest.UserContext)) { throw new ArgumentException("Duplicate user context in request"); } var counterAggregator = new CounterAggregator(counterRequest.QueryParameters); var shouldMergeSamples = DistributedQueryClient.ShouldMergeTimeBuckets(counterRequest.QueryParameters); counterRequest.QueryParameters = counterAggregator.ApplyPercentileCalculationAggregation(counterRequest.QueryParameters); this.requestMapping.Add(counterRequest.UserContext, new Tuple<bool, CounterAggregator>(shouldMergeSamples, counterAggregator)); } }
/// <summary> /// Run a distributed (tiered) query based on the parameters in the original request. Split the sources into N blocks (N is determined /// by the MaxFanout setting). Client will select a (random) leader for each block and send the request downstream. Client will merge all responses /// and in the case of failure will include diagnostics for each server in the chunk /// </summary> /// <param name="counterName">Name of the counter to query.</param> /// <param name="request">Base request to be distributed into blocks.</param> /// <param name="queryParameters">Query parameters for the counter.</param> /// <param name="dimensionSet">DimensionSet used to quickly merge per-sample query dimensions.</param> /// <returns>Aggregated response optionally returning per-source diagnostics. </returns> public async Task <CounterQueryResponse> CounterQuery(string counterName, TieredRequest request, IDictionary <string, string> queryParameters, DimensionSet dimensionSet) { if (string.IsNullOrEmpty(counterName)) { throw new ArgumentException("No counter name specified", "counterName"); } if (request == null) { throw new ArgumentNullException("request"); } if (dimensionSet == null) { throw new ArgumentNullException("dimensionSet"); } var counterAggregator = new CounterAggregator(dimensionSet); // if the client requested a percentile and there are multiple sources we let the aggregator apply that filtering after data collection if (HasSources(request)) { queryParameters = counterAggregator.ApplyPercentileCalculationAggregation(queryParameters); } var command = Protocol.BuildCounterRequestCommand(RestCommands.CounterQueryCommand, counterName, queryParameters); return(await this.Execute(request, command, counterAggregator.AddMachineResponse, () => counterAggregator.GetResponse(ShouldMergeTimeBuckets(queryParameters)))); }
/// <summary> /// Constructor that validates the query request and initializes internal state and fixes/cleans up the individual queries /// </summary> public BatchResponseAggregator(BatchQueryRequest request) { if (request == null) { throw new ArgumentNullException("request"); } if (request.Queries == null || request.Queries.Count == 0) { throw new ArgumentException("No queries provided", "request"); } foreach (var counterRequest in request.Queries) { if (string.IsNullOrEmpty(counterRequest.UserContext)) { counterRequest.UserContext = Guid.NewGuid().ToString("D"); } else if (this.requestMapping.ContainsKey(counterRequest.UserContext)) { throw new ArgumentException("Duplicate user context in request"); } var counterAggregator = new CounterAggregator(counterRequest.QueryParameters); var shouldMergeSamples = DistributedQueryClient.ShouldMergeTimeBuckets(counterRequest.QueryParameters); counterRequest.QueryParameters = counterAggregator.ApplyPercentileCalculationAggregation(counterRequest.QueryParameters); this.requestMapping.Add(counterRequest.UserContext, new Tuple <bool, CounterAggregator>(shouldMergeSamples, counterAggregator)); } }