Esempio n. 1
0
  private void doSnapshotAll(SnapshotAllResult result) throws Exception {
    //
    // create list of snapshots that will be executed
    //
    ArrayList<SnapshotTask> snapshotTasks = new ArrayList<SnapshotTask>();
    for (Observer<D> observer : observers.values()) {
      snapshotTasks.add(new SnapshotTask(observer, result.beginTimestamp));
    }
    result.snapshotsAttempted = snapshotTasks.size();

    // this will run all the update tasks and wait for them all to finish
    executor.invokeAll(snapshotTasks);

    // create an aggregate for each group
    TreeMap<String, ObserveAggregateSnapshot<A>> aggs =
        new TreeMap<String, ObserveAggregateSnapshot<A>>();

    // process deltas from each observer
    for (Observer<D> observer : observers.values()) {

      // determine if last snapshot completed or failed
      if (observer.getConsecutiveSnapshotCompletedCount() > 0) {
        result.snapshotsCompleted++;
      } else {
        result.snapshotsFailed++;
      }

      // was this the first snapshot attempt for this observer?
      long snapshotAttempts = observer.getSnapshotAttemptCounter();

      // each group will aggregate the same delta snapshot from each observer
      ObserveDeltaSnapshot<D> ods = observer.getDeltaSnapshot();

      if (ods == null) {
        // logger.debug("delta snapshot for observer {} was null", observer.getName());
        SnapshotException e = observer.getException();
        if (e == null) {
          if (snapshotAttempts <= 1) {
            // first runs we don't expect any deltas
          } else {
            logger.error(
                "observer [{}] for service [{}] had null delta AND exception values (previous snapshot maybe failed?)",
                observer.getName(),
                getServiceName());
          }
        } else {
          // this is now logged in SnapshotTask below
          // logger.warn("exception during snapshot for observer " + observer.getName(), e);
        }
      } else {
        // period should be the same across all deltas
        TimePeriod period = ods.getPeriod();
        // TODO: verify periods match each other as safety check?

        // create or get aggregate for each group this observer belongs to
        for (String group : observer.configuration.getGroups()) {
          ObserveAggregateSnapshot<A> oas = aggs.get(group);
          if (oas == null) {
            oas = new ObserveAggregateSnapshot<A>(period, aggregateClass.newInstance());
            aggs.put(group, oas);
          }
          oas.add(observer.getName(), ods.getData());
        }
      }
    }

    if (snapshotAllAttemptedCounter.get() > 1 && aggs.isEmpty()) {
      logger.warn(
          "snapshotAll() for service [{}] generated no aggregated snapshots!",
          this.getServiceName());
    }

    // at this point, the new snapshots from each observer have generated
    // new aggregates for this point-in-time -- add this to our rolling time series
    for (String group : aggs.keySet()) {
      // last aggregate snapshot
      ObserveAggregateSnapshot<A> oas = aggs.get(group);

      // get or create new series of aggregate snapshots for each group
      TimeSeries<ObserveAggregateSnapshot<A>> aggseries = snapshots.get(group);

      if (aggseries == null) {
        // figure out capacity of time series (retentionTime / step + fudgeFactor)
        long retentionMillis = getRetentionMillis();
        int initialCapacity = (int) (retentionMillis / this.serviceConfig.getStepMillis()) + 2;
        logger.info(
            "Creating new TimeSeries for service [{}] group [{}] with retentionMillis="
                + retentionMillis
                + "; initialCapacity="
                + initialCapacity,
            getServiceName(),
            group);
        aggseries = new TimeSeries<ObserveAggregateSnapshot<A>>(retentionMillis, initialCapacity);
        snapshots.put(group, aggseries);
      }

      // add aggregate snapshot to the time series for each group
      // this will also prune old snapshots that are older than the retention period
      // the timestamp of the aggregate becomes the relative "now" timestamp for calculating
      // retentions
      // this is how we'll always at least keep "current" times
      aggseries.add(oas, oas.getTimestamp());

      // create an updated summary for each interval for this group
      SummaryGroupFactory<S, A> sfg =
          new SummaryGroupFactory<S, A>(
              oas.getTimestamp(), this.summaryClass, this.serviceConfig.getPeriods());

      sfg.beginAll();

      Iterator<ObserveAggregateSnapshot<A>> it = aggseries.getSeries().iterator();
      while (it.hasNext()) {
        ObserveAggregateSnapshot<A> tempoas = it.next();
        sfg.summarize(tempoas.getPeriod(), tempoas.getAggregate());
      }

      sfg.completeAll();

      SummaryGroup<S> sg = sfg.createSummaryGroup();
      summary.put(group, sg);
    }
  }