Ejemplo n.º 1
0
 ImmutableMap<Service, Long> startupTimes() {
   List<Entry<Service, Long>> loadTimes;
   monitor.enter();
   try {
     loadTimes = Lists.newArrayListWithCapacity(startupTimers.size());
     // N.B. There will only be an entry in the map if the service has started
     for (Entry<Service, Stopwatch> entry : startupTimers.entrySet()) {
       Service service = entry.getKey();
       Stopwatch stopWatch = entry.getValue();
       if (!stopWatch.isRunning() && !(service instanceof NoOpService)) {
         loadTimes.add(Maps.immutableEntry(service, stopWatch.elapsed(MILLISECONDS)));
       }
     }
   } finally {
     monitor.leave();
   }
   Collections.sort(
       loadTimes,
       Ordering.<Long>natural()
           .onResultOf(
               new Function<Entry<Service, Long>, Long>() {
                 @Override
                 public Long apply(Map.Entry<Service, Long> input) {
                   return input.getValue();
                 }
               }));
   ImmutableMap.Builder<Service, Long> builder = ImmutableMap.builder();
   for (Entry<Service, Long> entry : loadTimes) {
     builder.put(entry);
   }
   return builder.build();
 }
Ejemplo n.º 2
0
    /**
     * Updates the state with the given service transition.
     *
     * <p>This method performs the main logic of ServiceManager in the following steps.
     *
     * <ol>
     *   <li>Update the {@link #servicesByState()}
     *   <li>Update the {@link #startupTimers}
     *   <li>Based on the new state queue listeners to run
     *   <li>Run the listeners (outside of the lock)
     * </ol>
     */
    void transitionService(final Service service, State from, State to) {
      checkNotNull(service);
      checkArgument(from != to);
      monitor.enter();
      try {
        transitioned = true;
        if (!ready) {
          return;
        }
        // Update state.
        checkState(
            servicesByState.remove(from, service),
            "Service %s not at the expected location in the state map %s",
            service,
            from);
        checkState(
            servicesByState.put(to, service),
            "Service %s in the state map unexpectedly at %s",
            service,
            to);
        // Update the timer
        Stopwatch stopwatch = startupTimers.get(service);
        if (stopwatch == null) {
          // This means the service was started by some means other than ServiceManager.startAsync
          stopwatch = Stopwatch.createStarted();
          startupTimers.put(service, stopwatch);
        }
        if (to.compareTo(RUNNING) >= 0 && stopwatch.isRunning()) {
          // N.B. if we miss the STARTING event then we may never record a startup time.
          stopwatch.stop();
          if (!(service instanceof NoOpService)) {
            logger.log(Level.FINE, "Started {0} in {1}.", new Object[] {service, stopwatch});
          }
        }
        // Queue our listeners

        // Did a service fail?
        if (to == FAILED) {
          fireFailedListeners(service);
        }

        if (states.count(RUNNING) == numberOfServices) {
          // This means that the manager is currently healthy. N.B. If other threads call isHealthy
          // they are not guaranteed to get 'true', because any service could fail right now.
          fireHealthyListeners();
        } else if (states.count(TERMINATED) + states.count(FAILED) == numberOfServices) {
          fireStoppedListeners();
        }
      } finally {
        monitor.leave();
        // Run our executors outside of the lock
        executeListeners();
      }
    }