예제 #1
0
 @Override
 public void stopping(State from) {
   ServiceManagerState state = this.state.get();
   if (state != null) {
     state.transitionService(service, from, STOPPING);
   }
 }
예제 #2
0
 @Override
 public void running() {
   ServiceManagerState state = this.state.get();
   if (state != null) {
     state.transitionService(service, STARTING, RUNNING);
   }
 }
예제 #3
0
 @Override
 public void starting() {
   ServiceManagerState state = this.state.get();
   if (state != null) {
     state.transitionService(service, NEW, STARTING);
     if (!(service instanceof NoOpService)) {
       logger.log(Level.FINE, "Starting {0}.", service);
     }
   }
 }
예제 #4
0
 @Override
 public void terminated(State from) {
   ServiceManagerState state = this.state.get();
   if (state != null) {
     if (!(service instanceof NoOpService)) {
       logger.log(
           Level.FINE,
           "Service {0} has terminated. Previous state was: {1}",
           new Object[] {service, from});
     }
     state.transitionService(service, from, TERMINATED);
   }
 }
예제 #5
0
 @Override
 public void failed(State from, Throwable failure) {
   ServiceManagerState state = this.state.get();
   if (state != null) {
     // Log before the transition, so that if the process exits in response to server failure,
     // there is a higher likelihood that the cause will be in the logs.
     if (!(service instanceof NoOpService)) {
       logger.log(
           Level.SEVERE,
           "Service " + service + " has failed in the " + from + " state.",
           failure);
     }
     state.transitionService(service, from, FAILED);
   }
 }
예제 #6
0
 /**
  * Initiates service {@linkplain Service#startAsync startup} on all the services being managed. It
  * is only valid to call this method if all of the services are {@linkplain State#NEW new}.
  *
  * @return this
  * @throws IllegalStateException if any of the Services are not {@link State#NEW new} when the
  *     method is called.
  */
 public ServiceManager startAsync() {
   for (Service service : services) {
     State state = service.state();
     checkState(state == NEW, "Service %s is %s, cannot start it.", service, state);
   }
   for (Service service : services) {
     try {
       state.tryStartTiming(service);
       service.startAsync();
     } catch (IllegalStateException e) {
       // This can happen if the service has already been started or stopped (e.g. by another
       // service or listener). Our contract says it is safe to call this method if
       // all services were NEW when it was called, and this has already been verified above, so we
       // don't propagate the exception.
       logger.log(Level.WARNING, "Unable to start Service " + service, e);
     }
   }
   return this;
 }
예제 #7
0
 /**
  * Returns the service load times. This value will only return startup times for services that
  * have finished starting.
  *
  * @return Map of services and their corresponding startup time in millis, the map entries will be
  *     ordered by startup time.
  */
 public ImmutableMap<Service, Long> startupTimes() {
   return state.startupTimes();
 }
예제 #8
0
 /**
  * Provides a snapshot of the current state of all the services under management.
  *
  * <p>N.B. This snapshot is guaranteed to be consistent, i.e. the set of states returned will
  * correspond to a point in time view of the services.
  */
 public ImmutableMultimap<State, Service> servicesByState() {
   return state.servicesByState();
 }
예제 #9
0
 /**
  * Waits for the all the services to reach a terminal state for no more than the given time. After
  * this method returns all services will either be {@linkplain Service.State#TERMINATED
  * terminated} or {@linkplain Service.State#FAILED failed}.
  *
  * @param timeout the maximum time to wait
  * @param unit the time unit of the timeout argument
  * @throws TimeoutException if not all of the services have stopped within the deadline
  */
 public void awaitStopped(long timeout, TimeUnit unit) throws TimeoutException {
   state.awaitStopped(timeout, unit);
 }
예제 #10
0
 /**
  * Waits for the all the services to reach a terminal state. After this method returns all
  * services will either be {@linkplain Service.State#TERMINATED terminated} or {@linkplain
  * Service.State#FAILED failed}.
  */
 public void awaitStopped() {
   state.awaitStopped();
 }
예제 #11
0
 /**
  * Waits for the {@link ServiceManager} to become {@linkplain #isHealthy() healthy} for no more
  * than the given time. The manager will become healthy after all the component services have
  * reached the {@linkplain State#RUNNING running} state.
  *
  * @param timeout the maximum time to wait
  * @param unit the time unit of the timeout argument
  * @throws TimeoutException if not all of the services have finished starting within the deadline
  * @throws IllegalStateException if the service manager reaches a state from which it cannot
  *     become {@linkplain #isHealthy() healthy}.
  */
 public void awaitHealthy(long timeout, TimeUnit unit) throws TimeoutException {
   state.awaitHealthy(timeout, unit);
 }
예제 #12
0
 /**
  * Waits for the {@link ServiceManager} to become {@linkplain #isHealthy() healthy}. The manager
  * will become healthy after all the component services have reached the {@linkplain State#RUNNING
  * running} state.
  *
  * @throws IllegalStateException if the service manager reaches a state from which it cannot
  *     become {@linkplain #isHealthy() healthy}.
  */
 public void awaitHealthy() {
   state.awaitHealthy();
 }
예제 #13
0
 /**
  * Registers a {@link Listener} to be run when this {@link ServiceManager} changes state. The
  * listener will not have previous state changes replayed, so it is suggested that listeners are
  * added before any of the managed services are {@linkplain Service#startAsync started}.
  *
  * <p>{@code addListener} guarantees execution ordering across calls to a given listener but not
  * across calls to multiple listeners. Specifically, a given listener will have its callbacks
  * invoked in the same order as the underlying service enters those states. Additionally, at most
  * one of the listener's callbacks will execute at once. However, multiple listeners' callbacks
  * may execute concurrently, and listeners may execute in an order different from the one in which
  * they were registered.
  *
  * <p>RuntimeExceptions thrown by a listener will be caught and logged.
  *
  * @param listener the listener to run when the manager changes state
  */
 public void addListener(Listener listener) {
   state.addListener(listener, directExecutor());
 }
예제 #14
0
 /**
  * Registers a {@link Listener} to be {@linkplain Executor#execute executed} on the given
  * executor. The listener will not have previous state changes replayed, so it is suggested that
  * listeners are added before any of the managed services are {@linkplain Service#startAsync
  * started}.
  *
  * <p>{@code addListener} guarantees execution ordering across calls to a given listener but not
  * across calls to multiple listeners. Specifically, a given listener will have its callbacks
  * invoked in the same order as the underlying service enters those states. Additionally, at most
  * one of the listener's callbacks will execute at once. However, multiple listeners' callbacks
  * may execute concurrently, and listeners may execute in an order different from the one in which
  * they were registered.
  *
  * <p>RuntimeExceptions thrown by a listener will be caught and logged. Any exception thrown
  * during {@code Executor.execute} (e.g., a {@code RejectedExecutionException}) will be caught and
  * logged.
  *
  * <p>For fast, lightweight listeners that would be safe to execute in any thread, consider
  * calling {@link #addListener(Listener)}.
  *
  * @param listener the listener to run when the manager changes state
  * @param executor the executor in which the listeners callback methods will be run.
  */
 public void addListener(Listener listener, Executor executor) {
   state.addListener(listener, executor);
 }