001/*
002 * Copyright (C) 2009 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.util.concurrent;
018
019import com.google.common.annotations.Beta;
020
021import java.util.concurrent.ExecutionException;
022import java.util.concurrent.Executor;
023import java.util.concurrent.TimeUnit;
024import java.util.concurrent.TimeoutException;
025
026/**
027 * An object with an operational state, plus asynchronous {@link #startAsync()} and
028 * {@link #stopAsync()} lifecycle methods to transition between states. Example services include
029 * webservers, RPC servers and timers.
030 *
031 * <p>The normal lifecycle of a service is:
032 * <ul>
033 *   <li>{@linkplain State#NEW NEW} -&gt;
034 *   <li>{@linkplain State#STARTING STARTING} -&gt;
035 *   <li>{@linkplain State#RUNNING RUNNING} -&gt;
036 *   <li>{@linkplain State#STOPPING STOPPING} -&gt;
037 *   <li>{@linkplain State#TERMINATED TERMINATED}
038 * </ul>
039 *
040 * <p>There are deviations from this if there are failures or if {@link Service#stopAsync} is called
041 * before the {@link Service} reaches the {@linkplain State#RUNNING RUNNING} state. The set of legal
042 * transitions form a <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">DAG</a>,
043 * therefore every method of the listener will be called at most once. N.B. The {@link State#FAILED}
044 * and {@link State#TERMINATED} states are terminal states, once a service enters either of these
045 * states it cannot ever leave them.
046 *
047 * <p>Implementors of this interface are strongly encouraged to extend one of the abstract classes
048 * in this package which implement this interface and make the threading and state management
049 * easier.
050 *
051 * @author Jesse Wilson
052 * @author Luke Sandberg
053 * @since 9.0 (in 1.0 as {@code com.google.common.base.Service})
054 */
055@Beta
056public interface Service {
057  /**
058   * If the service state is {@link State#NEW}, this initiates service startup and returns
059   * immediately. If the service has already been started, this method returns immediately without
060   * taking action. A stopped service may not be restarted.
061   *
062   * @deprecated Use {@link #startAsync()} instead of this method to start the {@link Service} or
063   * use a {@link Listener} to asynchronously wait for service startup.
064   *
065   * @return a future for the startup result, regardless of whether this call initiated startup.
066   *         Calling {@link ListenableFuture#get} will block until the service has finished
067   *         starting, and returns one of {@link State#RUNNING}, {@link State#STOPPING} or
068   *         {@link State#TERMINATED}. If the service fails to start, {@link ListenableFuture#get}
069   *         will throw an {@link ExecutionException}, and the service's state will be
070   *         {@link State#FAILED}. If it has already finished starting, {@link ListenableFuture#get}
071   *         returns immediately. Cancelling this future has no effect on the service.
072   */
073  @Deprecated ListenableFuture<State> start();
074
075  /**
076   * Initiates service startup (if necessary), returning once the service has finished starting.
077   * Unlike calling {@code start().get()}, this method throws no checked exceptions, and it cannot
078   * be {@linkplain Thread#interrupt interrupted}.
079   *
080   * @deprecated Use {@link #startAsync()} and {@link #awaitRunning} instead of this method.
081   *
082   * @throws UncheckedExecutionException if startup failed
083   * @return the state of the service when startup finished.
084   */
085  @Deprecated State startAndWait();
086
087  /**
088   * If the service state is {@link State#NEW}, this initiates service startup and returns
089   * immediately. A stopped service may not be restarted.
090   *
091   * @return this
092   * @throws IllegalStateException if the service is not {@link State#NEW}
093   *
094   * @since 15.0
095   */
096  Service startAsync();
097
098  /**
099   * Returns {@code true} if this service is {@linkplain State#RUNNING running}.
100   */
101  boolean isRunning();
102
103  /**
104   * Returns the lifecycle state of the service.
105   */
106  State state();
107
108  /**
109   * If the service is {@linkplain State#STARTING starting} or {@linkplain State#RUNNING running},
110   * this initiates service shutdown and returns immediately. If the service is
111   * {@linkplain State#NEW new}, it is {@linkplain State#TERMINATED terminated} without having been
112   * started nor stopped. If the service has already been stopped, this method returns immediately
113   * without taking action.
114   *
115   * @deprecated Use {@link #stopAsync} instead of this method to initiate service shutdown or use a
116   * service {@link Listener} to asynchronously wait for service shutdown.
117   *
118   * @return a future for the shutdown result, regardless of whether this call initiated shutdown.
119   *         Calling {@link ListenableFuture#get} will block until the service has finished shutting
120   *         down, and either returns {@link State#TERMINATED} or throws an
121   *         {@link ExecutionException}. If it has already finished stopping,
122   *         {@link ListenableFuture#get} returns immediately. Cancelling this future has no effect
123   *         on the service.
124   */
125  @Deprecated ListenableFuture<State> stop();
126
127  /**
128   * Initiates service shutdown (if necessary), returning once the service has finished stopping. If
129   * this is {@link State#STARTING}, startup will be cancelled. If this is {@link State#NEW}, it is
130   * {@link State#TERMINATED terminated} without having been started nor stopped. Unlike calling
131   * {@code stop().get()}, this method throws no checked exceptions.
132   *
133   * @deprecated Use {@link #stopAsync} and {@link #awaitTerminated} instead of this method.
134   *
135   * @throws UncheckedExecutionException if the service has failed or fails during shutdown
136   * @return the state of the service when shutdown finished.
137   */
138  @Deprecated State stopAndWait();
139
140  /**
141   * If the service is {@linkplain State#STARTING starting} or {@linkplain State#RUNNING running},
142   * this initiates service shutdown and returns immediately. If the service is
143   * {@linkplain State#NEW new}, it is {@linkplain State#TERMINATED terminated} without having been
144   * started nor stopped. If the service has already been stopped, this method returns immediately
145   * without taking action.
146   *
147   * @return this
148   * @since 15.0
149   */
150  Service stopAsync();
151
152  /**
153   * Waits for the {@link Service} to reach the {@linkplain State#RUNNING running state}.
154   *
155   * @throws IllegalStateException if the service reaches a state from which it is not possible to
156   *     enter the {@link State#RUNNING} state. e.g. if the {@code state} is
157   *     {@code State#TERMINATED} when this method is called then this will throw an
158   *     IllegalStateException.
159   *
160   * @since 15.0
161   */
162  void awaitRunning();
163
164  /**
165   * Waits for the {@link Service} to reach the {@linkplain State#RUNNING running state} for no
166   * more than the given time.
167   *
168   * @param timeout the maximum time to wait
169   * @param unit the time unit of the timeout argument
170   * @throws TimeoutException if the service has not reached the given state within the deadline
171   * @throws IllegalStateException if the service reaches a state from which it is not possible to
172   *     enter the {@link State#RUNNING RUNNING} state. e.g. if the {@code state} is
173   *     {@code State#TERMINATED} when this method is called then this will throw an
174   *     IllegalStateException.
175   *
176   * @since 15.0
177   */
178  void awaitRunning(long timeout, TimeUnit unit) throws TimeoutException;
179
180  /**
181   * Waits for the {@link Service} to reach the {@linkplain State#TERMINATED terminated state}.
182   *
183   * @throws IllegalStateException if the service {@linkplain State#FAILED fails}.
184   *
185   * @since 15.0
186   */
187  void awaitTerminated();
188
189  /**
190   * Waits for the {@link Service} to reach a terminal state (either
191   * {@link Service.State#TERMINATED terminated} or {@link Service.State#FAILED failed}) for no
192   * more than the given time.
193   *
194   * @param timeout the maximum time to wait
195   * @param unit the time unit of the timeout argument
196   * @throws TimeoutException if the service has not reached the given state within the deadline
197   * @throws IllegalStateException if the service {@linkplain State#FAILED fails}.
198   * @since 15.0
199   */
200  void awaitTerminated(long timeout, TimeUnit unit) throws TimeoutException;
201
202  /**
203   * Returns the {@link Throwable} that caused this service to fail.
204   *
205   * @throws IllegalStateException if this service's state isn't {@linkplain State#FAILED FAILED}.
206   *
207   * @since 14.0
208   */
209  Throwable failureCause();
210
211  /**
212   * Registers a {@link Listener} to be {@linkplain Executor#execute executed} on the given
213   * executor.  The listener will have the corresponding transition method called whenever the
214   * service changes state. The listener will not have previous state changes replayed, so it is
215   * suggested that listeners are added before the service starts.
216   *
217   * <p>There is no guaranteed ordering of execution of listeners, but any listener added through
218   * this method is guaranteed to be called whenever there is a state change.
219   *
220   * <p>Exceptions thrown by a listener will be propagated up to the executor. Any exception thrown
221   * during {@code Executor.execute} (e.g., a {@code RejectedExecutionException} or an exception
222   * thrown by {@linkplain MoreExecutors#sameThreadExecutor inline execution}) will be caught and
223   * logged.
224   *
225   * @param listener the listener to run when the service changes state is complete
226   * @param executor the executor in which the listeners callback methods will be run. For fast,
227   *     lightweight listeners that would be safe to execute in any thread, consider
228   *     {@link MoreExecutors#sameThreadExecutor}.
229   * @since 13.0
230   */
231  void addListener(Listener listener, Executor executor);
232
233  /**
234   * The lifecycle states of a service.
235   *
236   * <p>The ordering of the {@link State} enum is defined such that if there is a state transition
237   * from {@code A -> B} then {@code A.compareTo(B} < 0}.  N.B. The converse is not true, i.e. if
238   * {@code A.compareTo(B} < 0} then there is <b>not</b> guaranteed to be a valid state transition
239   * {@code A -> B}.
240   *
241   * @since 9.0 (in 1.0 as {@code com.google.common.base.Service.State})
242   */
243  @Beta // should come out of Beta when Service does
244  enum State {
245    /**
246     * A service in this state is inactive. It does minimal work and consumes
247     * minimal resources.
248     */
249    NEW {
250      @Override boolean isTerminal() {
251        return false;
252      }
253    },
254
255    /**
256     * A service in this state is transitioning to {@link #RUNNING}.
257     */
258    STARTING {
259      @Override boolean isTerminal() {
260        return false;
261      }
262    },
263
264    /**
265     * A service in this state is operational.
266     */
267    RUNNING {
268      @Override boolean isTerminal() {
269        return false;
270      }
271    },
272
273    /**
274     * A service in this state is transitioning to {@link #TERMINATED}.
275     */
276    STOPPING {
277      @Override boolean isTerminal() {
278        return false;
279      }
280    },
281
282    /**
283     * A service in this state has completed execution normally. It does minimal work and consumes
284     * minimal resources.
285     */
286    TERMINATED {
287      @Override boolean isTerminal() {
288        return true;
289      }
290    },
291
292    /**
293     * A service in this state has encountered a problem and may not be operational. It cannot be
294     * started nor stopped.
295     */
296    FAILED {
297      @Override boolean isTerminal() {
298        return true;
299      }
300    };
301
302    /** Returns true if this state is terminal. */
303    abstract boolean isTerminal();
304  }
305
306  /**
307   * A listener for the various state changes that a {@link Service} goes through in its lifecycle.
308   *
309   * <p>All methods are no-ops by default, implementors should override the ones they care about.
310   *
311   * @author Luke Sandberg
312   * @since 15.0 (present as an interface in 13.0)
313   */
314  @Beta // should come out of Beta when Service does
315  abstract class Listener {
316    /**
317     * Called when the service transitions from {@linkplain State#NEW NEW} to
318     * {@linkplain State#STARTING STARTING}. This occurs when {@link Service#start} or
319     * {@link Service#startAndWait} is called the first time.
320     */
321    public void starting() {}
322
323    /**
324     * Called when the service transitions from {@linkplain State#STARTING STARTING} to
325     * {@linkplain State#RUNNING RUNNING}. This occurs when a service has successfully started.
326     */
327    public void running() {}
328
329    /**
330     * Called when the service transitions to the {@linkplain State#STOPPING STOPPING} state. The
331     * only valid values for {@code from} are {@linkplain State#STARTING STARTING} or
332     * {@linkplain State#RUNNING RUNNING}.  This occurs when {@link Service#stop} is called.
333     *
334     * @param from The previous state that is being transitioned from.
335     */
336    public void stopping(State from) {}
337
338    /**
339     * Called when the service transitions to the {@linkplain State#TERMINATED TERMINATED} state.
340     * The {@linkplain State#TERMINATED TERMINATED} state is a terminal state in the transition
341     * diagram.  Therefore, if this method is called, no other methods will be called on the
342     * {@link Listener}.
343     *
344     * @param from The previous state that is being transitioned from.  The only valid values for
345     *     this are {@linkplain State#NEW NEW}, {@linkplain State#RUNNING RUNNING} or
346     *     {@linkplain State#STOPPING STOPPING}.
347     */
348    public void terminated(State from) {}
349
350    /**
351     * Called when the service transitions to the {@linkplain State#FAILED FAILED} state. The
352     * {@linkplain State#FAILED FAILED} state is a terminal state in the transition diagram.
353     * Therefore, if this method is called, no other methods will be called on the {@link Listener}.
354     *
355     * @param from The previous state that is being transitioned from.  Failure can occur in any
356     *     state with the exception of {@linkplain State#NEW NEW} or
357     *     {@linkplain State#TERMINATED TERMINATED}.
358     * @param failure The exception that caused the failure.
359     */
360    public void failed(State from, Throwable failure) {}
361  }
362}