Service services. This class
provides methods for #startAsync() starting, #stopAsync() stopping and
#servicesByState inspecting a collection of Service services.
Additionally, users can monitor state transitions with the Listener listener
mechanism.
While it is recommended that service lifecycles be managed via this class, state transitions
initiated via other mechanisms do not impact the correctness of its methods. For example, if the
services are started by some mechanism besides #startAsync, the listeners will be invoked
when appropriate and #awaitHealthy will still work as expected.
Here is a simple example of how to use a ServiceManager to start a server.
class Server {
public static void main(String[] args) {
Set<Service> services = ...;
ServiceManager manager = new ServiceManager(services);
manager.addListener(new Listener() {
public void stopped() {}
public void healthy() {
// Services have been initialized and are healthy, start accepting requests...
}
public void failure(Service service) {
// Something failed, at this point we could log it, notify a load balancer, or take
// some other action. For now we will just exit.
System.exit(1);
}
},
MoreExecutors.directExecutor());
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
// Give the services 5 seconds to stop to ensure that we are responsive to shutdown
// requests.
try {
manager.stopAsync().awaitStopped(5, TimeUnit.SECONDS);
} catch (TimeoutException timeout) {
// stopping timed out
}
}
});
manager.startAsync(); // start all the services asynchronously
}
}
This class uses the ServiceManager's methods to start all of its services, to respond to service failure and to ensure that when the JVM is shutting down all the services are stopped.
- Since:
- 14.0
- Author:
- Luke Sandberg
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classA listener for the aggregate state changes of the services that are under management. -
Constructor Summary
ConstructorsConstructorDescriptionServiceManager(Iterable<? extends Service> services) Constructs a new instance for managing the given services. -
Method Summary
Modifier and TypeMethodDescriptionvoidaddListener(ServiceManager.Listener listener, Executor executor) Registers aListenerto beExecutor#execute executedon the given executor.voidWaits for theServiceManagerto become#isHealthy() healthy.voidawaitHealthy(long timeout, TimeUnit unit) Waits for theServiceManagerto become#isHealthy() healthyfor no more than the given time.voidawaitHealthy(Duration timeout) Waits for theServiceManagerto become#isHealthy() healthyfor no more than the given time.voidWaits for the all the services to reach a terminal state.voidawaitStopped(long timeout, TimeUnit unit) Waits for the all the services to reach a terminal state for no more than the given time.voidawaitStopped(Duration timeout) Waits for the all the services to reach a terminal state for no more than the given time.booleanReturns true if all services are currently in theState#RUNNING runningstate.dev.mccue.guava.collect.ImmutableSetMultimap<Service.State,Service> Provides a snapshot of the current state of all the services under management.Initiates serviceService#startAsync startupon all the services being managed.Returns the service load times.Returns the service load times.Initiates serviceService#stopAsync shutdownif necessary on all the services being managed.toString()
-
Constructor Details
-
ServiceManager
Constructs a new instance for managing the given services.- Parameters:
services- The services to manage- Throws:
IllegalArgumentException- if not all services areState#NEW newor if there are any duplicate services.
-
-
Method Details
-
addListener
Registers aListenerto beExecutor#execute executedon 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 areService#startAsync started.addListenerguarantees 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.RuntimeExceptions thrown by a listener will be caught and logged. Any exception thrown during
Executor.execute(e.g., aRejectedExecutionException) will be caught and logged.When selecting an executor, note that
directExecutoris dangerous in some cases. See the discussion in theListenableFuture#addListener ListenableFuture.addListenerdocumentation.- Parameters:
listener- the listener to run when the manager changes stateexecutor- the executor in which the listeners callback methods will be run.
-
startAsync
Initiates serviceService#startAsync startupon all the services being managed. It is only valid to call this method if all of the services areState#NEW new.- Returns:
- this
- Throws:
IllegalStateException- if any of the Services are notState#NEW newwhen the method is called.
-
awaitHealthy
public void awaitHealthy()Waits for theServiceManagerto become#isHealthy() healthy. The manager will become healthy after all the component services have reached theState#RUNNING runningstate.- Throws:
IllegalStateException- if the service manager reaches a state from which it cannot become#isHealthy() healthy.
-
awaitHealthy
Waits for theServiceManagerto become#isHealthy() healthyfor no more than the given time. The manager will become healthy after all the component services have reached theState#RUNNING runningstate.- Parameters:
timeout- the maximum time to wait- Throws:
TimeoutException- if not all of the services have finished starting within the deadlineIllegalStateException- if the service manager reaches a state from which it cannot become#isHealthy() healthy.- Since:
- 28.0
-
awaitHealthy
Waits for theServiceManagerto become#isHealthy() healthyfor no more than the given time. The manager will become healthy after all the component services have reached theState#RUNNING runningstate.- Parameters:
timeout- the maximum time to waitunit- the time unit of the timeout argument- Throws:
TimeoutException- if not all of the services have finished starting within the deadlineIllegalStateException- if the service manager reaches a state from which it cannot become#isHealthy() healthy.
-
stopAsync
Initiates serviceService#stopAsync shutdownif necessary on all the services being managed.- Returns:
- this
-
awaitStopped
public void awaitStopped()Waits for the all the services to reach a terminal state. After this method returns all services will either beService.State#TERMINATED terminatedorService.State#FAILED failed. -
awaitStopped
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 beService.State#TERMINATED terminatedorService.State#FAILED failed.- Parameters:
timeout- the maximum time to wait- Throws:
TimeoutException- if not all of the services have stopped within the deadline- Since:
- 28.0
-
awaitStopped
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 beService.State#TERMINATED terminatedorService.State#FAILED failed.- Parameters:
timeout- the maximum time to waitunit- the time unit of the timeout argument- Throws:
TimeoutException- if not all of the services have stopped within the deadline
-
isHealthy
public boolean isHealthy()Returns true if all services are currently in theState#RUNNING runningstate.Users who want more detailed information should use the
#servicesByStatemethod to get detailed information about which services are not running. -
servicesByState
Provides a snapshot of the current state of all the services under management.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.
- Since:
- 29.0 (present with return type
ImmutableMultimapsince 14.0)
-
startupTimes
Returns the service load times. This value will only return startup times for services that have finished starting.- Returns:
- Map of services and their corresponding startup time in millis, the map entries will be ordered by startup time.
-
startupDurations
Returns the service load times. This value will only return startup times for services that have finished starting.- Returns:
- Map of services and their corresponding startup time, the map entries will be ordered by startup time.
- Since:
- 31.0
-
toString
-