1/*
2 * Copyright (C) 2009 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.util.concurrent;
18
19import com.google.common.annotations.Beta;
20
21import java.util.concurrent.ExecutionException;
22
23/**
24 * An object with an operational state, plus asynchronous {@link #start()} and
25 * {@link #stop()} lifecycle methods to transfer into and out of this state.
26 * Example services include webservers, RPC servers and timers. The normal
27 * lifecycle of a service is:
28 * <ul>
29 *   <li>{@link State#NEW} -&gt;</li>
30 *   <li>{@link State#STARTING} -&gt;</li>
31 *   <li>{@link State#RUNNING} -&gt;</li>
32 *   <li>{@link State#STOPPING} -&gt;</li>
33 *   <li>{@link State#TERMINATED}</li>
34 * </ul>
35 *
36 * If the service fails while starting, running or stopping, its state will be
37 * {@link State#FAILED}, and its behavior is undefined. Such a service cannot be
38 * started nor stopped.
39 *
40 * <p>Implementors of this interface are strongly encouraged to extend one of
41 * the abstract classes in this package which implement this interface and
42 * make the threading and state management easier.
43 *
44 * @author Jesse Wilson
45 * @since 9.0 (in 1.0 as
46 *     {@code com.google.common.base.Service})
47 */
48@Beta // TODO(kevinb): make abstract class?
49public interface Service {
50  /**
51   * If the service state is {@link State#NEW}, this initiates service startup
52   * and returns immediately. If the service has already been started, this
53   * method returns immediately without taking action. A stopped service may not
54   * be restarted.
55   *
56   * @return a future for the startup result, regardless of whether this call
57   *     initiated startup. Calling {@link ListenableFuture#get} will block
58   *     until the service has finished starting, and returns one of {@link
59   *     State#RUNNING}, {@link State#STOPPING} or {@link State#TERMINATED}. If
60   *     the service fails to start, {@link ListenableFuture#get} will throw an
61   *     {@link ExecutionException}, and the service's state will be {@link
62   *     State#FAILED}. If it has already finished starting, {@link
63   *     ListenableFuture#get} returns immediately. Cancelling this future has
64   *     no effect on the service.
65   */
66  ListenableFuture<State> start();
67
68  /**
69   * Initiates service startup (if necessary), returning once the service has
70   * finished starting. Unlike calling {@code start().get()}, this method throws
71   * no checked exceptions, and it cannot be {@linkplain Thread#interrupt
72   * interrupted}.
73   *
74   * @throws UncheckedExecutionException if startup failed
75   * @return the state of the service when startup finished.
76   */
77  State startAndWait();
78
79  /**
80   * Returns {@code true} if this service is {@linkplain State#RUNNING running}.
81   */
82  boolean isRunning();
83
84  /**
85   * Returns the lifecycle state of the service.
86   */
87  State state();
88
89  /**
90   * If the service is {@linkplain State#STARTING starting} or {@linkplain
91   * State#RUNNING running}, this initiates service shutdown and returns
92   * immediately. If the service is {@linkplain State#NEW new}, it is
93   * {@linkplain State#TERMINATED terminated} without having been started nor
94   * stopped.  If the service has already been stopped, this method returns
95   * immediately without taking action.
96   *
97   * @return a future for the shutdown result, regardless of whether this call
98   *     initiated shutdown. Calling {@link ListenableFuture#get} will block
99   *     until the service has finished shutting down, and either returns
100   *     {@link State#TERMINATED} or throws an {@link ExecutionException}. If
101   *     it has already finished stopping, {@link ListenableFuture#get} returns
102   *     immediately.  Cancelling this future has no effect on the service.
103   */
104  ListenableFuture<State> stop();
105
106  /**
107   * Initiates service shutdown (if necessary), returning once the service has
108   * finished stopping. If this is {@link State#STARTING}, startup will be
109   * cancelled. If this is {@link State#NEW}, it is {@link State#TERMINATED
110   * terminated} without having been started nor stopped. Unlike calling {@code
111   * stop().get()}, this method throws no checked exceptions.
112   *
113   * @throws UncheckedExecutionException if shutdown failed
114   * @return the state of the service when shutdown finished.
115   */
116  State stopAndWait();
117
118  /**
119   * The lifecycle states of a service.
120   *
121   * @since 9.0 (in 1.0 as
122   *     {@code com.google.common.base.Service.State})
123   */
124  @Beta // should come out of Beta when Service does
125  enum State {
126    /**
127     * A service in this state is inactive. It does minimal work and consumes
128     * minimal resources.
129     */
130    NEW,
131
132    /**
133     * A service in this state is transitioning to {@link #RUNNING}.
134     */
135    STARTING,
136
137    /**
138     * A service in this state is operational.
139     */
140    RUNNING,
141
142    /**
143     * A service in this state is transitioning to {@link #TERMINATED}.
144     */
145    STOPPING,
146
147    /**
148     * A service in this state has completed execution normally. It does minimal
149     * work and consumes minimal resources.
150     */
151    TERMINATED,
152
153    /**
154     * A service in this state has encountered a problem and may not be
155     * operational. It cannot be started nor stopped.
156     */
157    FAILED
158  }
159}
160