@Beta public final class ServiceManager extends Object
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.
| Modifier and Type | Class and Description |
|---|---|
static class |
ServiceManager
A listener for the aggregate state changes of the services that are under management.
|
| Constructor and Description |
|---|
ServiceManager(Iterable
Constructs a new instance for managing the given services.
|
| Modifier and Type | Method and Description |
|---|---|
void |
addListener(ServiceManager
Registers a
ServiceManager.Listener to be run when this
ServiceManager changes state.
|
void |
addListener(ServiceManager
Registers a
ServiceManager.Listener to be
executed on the given executor.
|
void |
awaitHealthy()
Waits for the
ServiceManager to become
healthy.
|
void |
awaitHealthy(long timeout, TimeUnit
Waits for the
ServiceManager to become
healthy for no more than the given time.
|
void |
awaitStopped()
Waits for the all the services to reach a terminal state.
|
void |
awaitStopped(long timeout, TimeUnit
Waits for the all the services to reach a terminal state for no more than the given time.
|
boolean |
isHealthy()
Returns true if all services are currently in the
running state.
|
ImmutableMultimap |
servicesByState()
Provides a snapshot of the current state of all the services under management.
|
ServiceManager |
startAsync()
Initiates service
startup on all the services being managed.
|
ImmutableMap |
startupTimes()
Returns the service load times.
|
ServiceManager |
stopAsync()
Initiates service
shutdown if necessary on all the services being managed.
|
String |
toString()
|
public ServiceManager(Iterable<? extends Service > services)
services - The services to manage
IllegalArgumentException - if not all services are
new or if there are any duplicate services.
public void addListener(ServiceManager.Listener listener, Executor executor)
ServiceManager.Listener to be
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
started.
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.
RuntimeExceptions thrown by a listener will be caught and logged. Any exception thrown during Executor.execute (e.g., a RejectedExecutionException) will be caught and logged.
For fast, lightweight listeners that would be safe to execute in any thread, consider calling addListener(Listener).
listener - the listener to run when the manager changes state
executor - the executor in which the listeners callback methods will be run.
public void addListener(ServiceManager.Listener listener)
ServiceManager.Listener to be run when this
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
started.
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.
RuntimeExceptions thrown by a listener will be caught and logged.
listener - the listener to run when the manager changes state
public ServiceManagerstartAsync()
IllegalStateException - if any of the Services are not
new when the method is called.
public void awaitHealthy()
ServiceManager to become
healthy. The manager will become healthy after all the component services have reached the
running state.
IllegalStateException - if the service manager reaches a state from which it cannot become
healthy.
public void awaitHealthy(long timeout,
TimeUnit unit)
throws TimeoutException
ServiceManager to become
healthy for no more than the given time. The manager will become healthy after all the component services have reached the
running state.
timeout - the maximum time to wait
unit - the time unit of the timeout argument
TimeoutException - if not all of the services have finished starting within the deadline
IllegalStateException - if the service manager reaches a state from which it cannot become
healthy.
public ServiceManagerstopAsync()
public void awaitStopped()
public void awaitStopped(long timeout,
TimeUnit unit)
throws TimeoutException
timeout - the maximum time to wait
unit - the time unit of the timeout argument
TimeoutException - if not all of the services have stopped within the deadline
public boolean isHealthy()
Users who want more detailed information should use the servicesByState() method to get detailed information about which services are not running.
public ImmutableMultimap<Service .State ,Service > servicesByState()
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 ImmutableMap<Service ,Long > startupTimes()
public StringtoString()