public static ActionBlock<StatsdMessage> CreateBlock(ITargetBlock<CounterBucket> target,
          string rootNamespace,
          IIntervalService intervalService,
          ITimeWindowService timeWindowService,
          ILog log)
        {
            var windows = new ConcurrentDictionary<string, ConcurrentDictionary<string, double>>();
            var root = rootNamespace;
            var ns = String.IsNullOrEmpty(rootNamespace) ? "" : rootNamespace + ".";

            var incoming = new ActionBlock<StatsdMessage>(p =>
              {
                  var calendargram = p as Calendargram;
                  var metricName = calendargram.Name + METRIC_IDENTIFIER_SEPARATOR + calendargram.Value;

                  var period = timeWindowService.GetTimeWindow().GetTimePeriod(calendargram.Period);
                  windows.AddOrUpdate(period,
                    (key) =>
                    {
                        var window = new ConcurrentDictionary<string, double>();
                        window.AddOrUpdate(metricName, (key2) => 1, (key2, oldValue) => 1);
                        return window;
                    },
                    (key, window) =>
                    {
                        window.AddOrUpdate(metricName, (key2) => 1, (key2, oldValue) => 1);
                        return window;
                    }
                  );
              },
              new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded });

            intervalService.Elapsed += (sender, e) =>
              {
                  if (windows.Count == 0)
                  {
                      return;
                  }
                  var currentTimeWindow = timeWindowService.GetTimeWindow();

                  var periodsNotPresent = windows
                      .ToArray()
                      .Where(p => !currentTimeWindow.AllPeriods.Contains(p.Key))
                      .Select(p => p.Key);

                  CounterBucket bucket;

                  foreach (var period in periodsNotPresent)
                  {
                      ConcurrentDictionary<String, double> window;
                      if (windows.TryRemove(period, out window))
                      {
                          var parts = period.Split(UNDERSCORE);
                          var qualifier = "." + parts[0] + "." + parts[1];

                          var metricsAndValues = window.ToArray();
                          var metrics = new Dictionary<String, double>();
                          for (int index = 0; index < metricsAndValues.Length; index++)
                          {
                              var metricName = metricsAndValues[index].Key.Split(
                                  METRIC_IDENTIFIER_SEPARATOR_SPLITTER, 
                                  StringSplitOptions.RemoveEmptyEntries
                              )[0] + qualifier;

                              if (metrics.ContainsKey(metricName))
                              {
                                  metrics[metricName] += 1;
                              }
                              else
                              {
                                  metrics[metricName] = 1;
                              }
                          }

                          var metricList = metrics.Select(metric =>
                          {
                              return new KeyValuePair<string, double>(
                                metric.Key,
                                metric.Value
                              );
                          }).ToArray();
                          bucket = new CounterBucket(metricList, e.Epoch, ns);
                          target.Post(bucket);
                      }
                  }
              };
            incoming.Completion.ContinueWith(p =>
              {
                  log.Info("TimedCounterAggregatorBlock completing.");
                  // Tell the upstream block that we're done
                  target.Complete();
              });
            return incoming;
        }
示例#2
0
 public TimeWindowController(ITimeWindowService timeWindowService, IFeatureService featureService)
 {
     _timeWindowService = timeWindowService ?? throw new ArgumentNullException(nameof(timeWindowService));
     _featureService    = featureService ?? throw new ArgumentNullException(nameof(featureService));
 }
示例#3
0
        public static ActionBlock <StatsdMessage> CreateBlock(ITargetBlock <CounterBucket> target,
                                                              string rootNamespace,
                                                              IIntervalService intervalService,
                                                              ITimeWindowService timeWindowService,
                                                              ILog log)
        {
            var windows = new ConcurrentDictionary <string, ConcurrentDictionary <string, double> >();
            var root    = rootNamespace;
            var ns      = String.IsNullOrEmpty(rootNamespace) ? "" : rootNamespace + ".";

            var incoming = new ActionBlock <StatsdMessage>(p =>
            {
                var calendargram = p as Calendargram;
                var metricName   = calendargram.Name + METRIC_IDENTIFIER_SEPARATOR + calendargram.Value;

                var period = timeWindowService.GetTimeWindow().GetTimePeriod(calendargram.Period);
                windows.AddOrUpdate(period,
                                    (key) =>
                {
                    var window = new ConcurrentDictionary <string, double>();
                    window.AddOrUpdate(metricName, (key2) => 1, (key2, oldValue) => 1);
                    return(window);
                },
                                    (key, window) =>
                {
                    window.AddOrUpdate(metricName, (key2) => 1, (key2, oldValue) => 1);
                    return(window);
                }
                                    );
            },
                                                           new ExecutionDataflowBlockOptions()
            {
                MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded
            });

            intervalService.Elapsed += (sender, e) =>
            {
                if (windows.Count == 0)
                {
                    return;
                }
                var currentTimeWindow = timeWindowService.GetTimeWindow();

                var periodsNotPresent = windows
                                        .ToArray()
                                        .Where(p => !currentTimeWindow.AllPeriods.Contains(p.Key))
                                        .Select(p => p.Key);

                CounterBucket bucket;

                foreach (var period in periodsNotPresent)
                {
                    ConcurrentDictionary <String, double> window;
                    if (windows.TryRemove(period, out window))
                    {
                        var parts     = period.Split(UNDERSCORE);
                        var qualifier = "." + parts[0] + "." + parts[1];

                        var metricsAndValues = window.ToArray();
                        var metrics          = new Dictionary <String, double>();
                        for (int index = 0; index < metricsAndValues.Length; index++)
                        {
                            var metricName = metricsAndValues[index].Key.Split(
                                METRIC_IDENTIFIER_SEPARATOR_SPLITTER,
                                StringSplitOptions.RemoveEmptyEntries
                                )[0] + qualifier;

                            if (metrics.ContainsKey(metricName))
                            {
                                metrics[metricName] += 1;
                            }
                            else
                            {
                                metrics[metricName] = 1;
                            }
                        }

                        var metricList = metrics.Select(metric =>
                        {
                            return(new KeyValuePair <string, double>(
                                       metric.Key,
                                       metric.Value
                                       ));
                        }).ToArray();
                        bucket = new CounterBucket(metricList, e.Epoch, ns);
                        target.Post(bucket);
                    }
                }
            };
            incoming.Completion.ContinueWith(p =>
            {
                log.Info("TimedCounterAggregatorBlock completing.");
                // Tell the upstream block that we're done
                target.Complete();
            });
            return(incoming);
        }