diff options
author | Yohann Roussel <yroussel@google.com> | 2014-03-19 16:25:37 +0100 |
---|---|---|
committer | Yohann Roussel <yroussel@google.com> | 2014-03-20 15:13:33 +0100 |
commit | 4eceb95409e844fdc33c9c706e1dc307bfd40303 (patch) | |
tree | ee9f4f3fc79f757c79081c336bce4f1782c6ccd8 /guava/src/com/google/common/util/concurrent/Service.java | |
parent | 3d2402901b1a6462e2cf47a6fd09711f327961c3 (diff) | |
download | toolchain_jack-4eceb95409e844fdc33c9c706e1dc307bfd40303.zip toolchain_jack-4eceb95409e844fdc33c9c706e1dc307bfd40303.tar.gz toolchain_jack-4eceb95409e844fdc33c9c706e1dc307bfd40303.tar.bz2 |
Initial Jack import.
Change-Id: I953cf0a520195a7187d791b2885848ad0d5a9b43
Diffstat (limited to 'guava/src/com/google/common/util/concurrent/Service.java')
-rw-r--r-- | guava/src/com/google/common/util/concurrent/Service.java | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/guava/src/com/google/common/util/concurrent/Service.java b/guava/src/com/google/common/util/concurrent/Service.java new file mode 100644 index 0000000..1c3bed6 --- /dev/null +++ b/guava/src/com/google/common/util/concurrent/Service.java @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2009 The Guava Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.common.util.concurrent; + +import com.google.common.annotations.Beta; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; + +/** + * An object with an operational state, plus asynchronous {@link #start()} and {@link #stop()} + * lifecycle methods to transition between states. Example services include webservers, RPC servers + * and timers. + * + * <p>The normal lifecycle of a service is: + * <ul> + * <li>{@linkplain State#NEW NEW} -> + * <li>{@linkplain State#STARTING STARTING} -> + * <li>{@linkplain State#RUNNING RUNNING} -> + * <li>{@linkplain State#STOPPING STOPPING} -> + * <li>{@linkplain State#TERMINATED TERMINATED} + * </ul> + * + * <p>There are deviations from this if there are failures or if {@link Service#stop} is called + * before the {@link Service} reaches the {@linkplain State#RUNNING RUNNING} state. The set of legal + * transitions form a <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">DAG</a>, + * therefore every method of the listener will be called at most once. N.B. The {@link State#FAILED} + * and {@link State#TERMINATED} states are terminal states, once a service enters either of these + * states it cannot ever leave them. + * + * <p>Implementors of this interface are strongly encouraged to extend one of the abstract classes + * in this package which implement this interface and make the threading and state management + * easier. + * + * @author Jesse Wilson + * @author Luke Sandberg + * @since 9.0 (in 1.0 as {@code com.google.common.base.Service}) + */ +@Beta +public interface Service { + /** + * If the service state is {@link State#NEW}, this initiates service startup and returns + * immediately. If the service has already been started, this method returns immediately without + * taking action. A stopped service may not be restarted. + * + * @return a future for the startup result, regardless of whether this call initiated startup. + * Calling {@link ListenableFuture#get} will block until the service has finished + * starting, and returns one of {@link State#RUNNING}, {@link State#STOPPING} or + * {@link State#TERMINATED}. If the service fails to start, {@link ListenableFuture#get} + * will throw an {@link ExecutionException}, and the service's state will be + * {@link State#FAILED}. If it has already finished starting, {@link ListenableFuture#get} + * returns immediately. Cancelling this future has no effect on the service. + */ + ListenableFuture<State> start(); + + /** + * Initiates service startup (if necessary), returning once the service has finished starting. + * Unlike calling {@code start().get()}, this method throws no checked exceptions, and it cannot + * be {@linkplain Thread#interrupt interrupted}. + * + * @throws UncheckedExecutionException if startup failed + * @return the state of the service when startup finished. + */ + State startAndWait(); + + /** + * Returns {@code true} if this service is {@linkplain State#RUNNING running}. + */ + boolean isRunning(); + + /** + * Returns the lifecycle state of the service. + */ + State state(); + + /** + * If the service is {@linkplain State#STARTING starting} or {@linkplain State#RUNNING running}, + * this initiates service shutdown and returns immediately. If the service is + * {@linkplain State#NEW new}, it is {@linkplain State#TERMINATED terminated} without having been + * started nor stopped. If the service has already been stopped, this method returns immediately + * without taking action. + * + * @return a future for the shutdown result, regardless of whether this call initiated shutdown. + * Calling {@link ListenableFuture#get} will block until the service has finished shutting + * down, and either returns {@link State#TERMINATED} or throws an + * {@link ExecutionException}. If it has already finished stopping, + * {@link ListenableFuture#get} returns immediately. Cancelling this future has no effect + * on the service. + */ + ListenableFuture<State> stop(); + + /** + * Initiates service shutdown (if necessary), returning once the service has finished stopping. If + * this is {@link State#STARTING}, startup will be cancelled. If this is {@link State#NEW}, it is + * {@link State#TERMINATED terminated} without having been started nor stopped. Unlike calling + * {@code stop().get()}, this method throws no checked exceptions. + * + * @throws UncheckedExecutionException if the service has failed or fails during shutdown + * @return the state of the service when shutdown finished. + */ + State stopAndWait(); + + /** + * Registers a {@link Listener} to be {@linkplain Executor#execute executed} on the given + * executor. The listener will have the corresponding transition method called whenever the + * service changes state. The listener will not have previous state changes replayed, so it is + * suggested that listeners are added before the service starts. + * + * <p>There is no guaranteed ordering of execution of listeners, but any listener added through + * this method is guaranteed to be called whenever there is a state change. + * + * <p>Exceptions thrown by a listener will be propagated up to the executor. Any exception thrown + * during {@code Executor.execute} (e.g., a {@code RejectedExecutionException} or an exception + * thrown by {@linkplain MoreExecutors#sameThreadExecutor inline execution}) will be caught and + * logged. + * + * @param listener the listener to run when the service changes state is complete + * @param executor the executor in which the the listeners callback methods will be run. For fast, + * lightweight listeners that would be safe to execute in any thread, consider + * {@link MoreExecutors#sameThreadExecutor}. + * @since 13.0 + */ + void addListener(Listener listener, Executor executor); + + /** + * The lifecycle states of a service. + * + * @since 9.0 (in 1.0 as {@code com.google.common.base.Service.State}) + */ + @Beta // should come out of Beta when Service does + enum State { + /** + * A service in this state is inactive. It does minimal work and consumes + * minimal resources. + */ + NEW, + + /** + * A service in this state is transitioning to {@link #RUNNING}. + */ + STARTING, + + /** + * A service in this state is operational. + */ + RUNNING, + + /** + * A service in this state is transitioning to {@link #TERMINATED}. + */ + STOPPING, + + /** + * A service in this state has completed execution normally. It does minimal work and consumes + * minimal resources. + */ + TERMINATED, + + /** + * A service in this state has encountered a problem and may not be operational. It cannot be + * started nor stopped. + */ + FAILED + } + + /** + * A listener for the various state changes that a {@link Service} goes through in its lifecycle. + * + * @author Luke Sandberg + * @since 13.0 + */ + @Beta // should come out of Beta when Service does + interface Listener { + /** + * Called when the service transitions from {@linkplain State#NEW NEW} to + * {@linkplain State#STARTING STARTING}. This occurs when {@link Service#start} or + * {@link Service#startAndWait} is called the first time. + */ + void starting(); + + /** + * Called when the service transitions from {@linkplain State#STARTING STARTING} to + * {@linkplain State#RUNNING RUNNING}. This occurs when a service has successfully started. + */ + void running(); + + /** + * Called when the service transitions to the {@linkplain State#STOPPING STOPPING} state. The + * only valid values for {@code from} are {@linkplain State#STARTING STARTING} or + * {@linkplain State#RUNNING RUNNING}. This occurs when {@link Service#stop} is called. + * + * @param from The previous state that is being transitioned from. + */ + void stopping(State from); + + /** + * Called when the service transitions to the {@linkplain State#TERMINATED TERMINATED} state. + * The {@linkplain State#TERMINATED TERMINATED} state is a terminal state in the transition + * diagram. Therefore, if this method is called, no other methods will be called on the + * {@link Listener}. + * + * @param from The previous state that is being transitioned from. The only valid values for + * this are {@linkplain State#NEW NEW}, {@linkplain State#RUNNING RUNNING} or + * {@linkplain State#STOPPING STOPPING}. + */ + void terminated(State from); + + /** + * Called when the service transitions to the {@linkplain State#FAILED FAILED} state. The + * {@linkplain State#FAILED FAILED} state is a terminal state in the transition diagram. + * Therefore, if this method is called, no other methods will be called on the {@link Listener}. + * + * @param from The previous state that is being transitioned from. Failure can occur in any + * state with the exception of {@linkplain State#NEW NEW} or + * {@linkplain State#TERMINATED TERMINATED}. + * @param failure The exception that caused the failure. + */ + void failed(State from, Throwable failure); + } +} |