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    
017    package com.google.common.util.concurrent;
018    
019    import com.google.common.annotations.Beta;
020    
021    import java.util.concurrent.ExecutionException;
022    
023    /**
024     * An object with an operational state, plus asynchronous {@link #start()} and
025     * {@link #stop()} lifecycle methods to transition between states.
026     * Example services include webservers, RPC servers and timers. 
027     * 
028     * <p>The normal lifecycle of a service is:
029     * <ul>
030     *   <li>{@link State#NEW} -&gt;</li>
031     *   <li>{@link State#STARTING} -&gt;</li>
032     *   <li>{@link State#RUNNING} -&gt;</li>
033     *   <li>{@link State#STOPPING} -&gt;</li>
034     *   <li>{@link State#TERMINATED}</li>
035     * </ul>
036     * 
037     * <p>The valid state transitions of a Service are:
038     * <ul>
039     *   <li>{@link State#NEW} -&gt; {@link State#STARTING}: This occurs when 
040     *      start() is called the first time and is the only valid state transition
041     *      from the NEW state.</li>
042     *   <li>{@link State#NEW} -&gt; {@link State#TERMINATED}: This occurs when 
043     *      stop() is called from the NEW state.</li>
044     *   <li>{@link State#STARTING} -&gt; {@link State#RUNNING}: This occurs when 
045     *      a service has successfully started</li>
046     *   <li>{@link State#STARTING} -&gt; {@link State#FAILED}: This occurs when a
047     *      service experiences an unrecoverable error while starting up</li>
048     *   <li>{@link State#STARTING} -&gt; {@link State#STOPPING}: This occurs when 
049     *      stop() is called while a service is starting up.</li>
050     *   <li>{@link State#RUNNING} -&gt; {@link State#STOPPING}: This occurs when 
051     *      stop() is called on a running service.</li>
052     *   <li>{@link State#RUNNING} -&gt; {@link State#FAILED}: This occurs when an 
053     *      unrecoverable error occurs while a service is running.</li>
054     *   <li>{@link State#STOPPING} -&gt; {@link State#FAILED}: This occurs when an
055     *      unrecoverable error occurs while a service is stopping.</li>
056     *   <li>{@link State#STOPPING} -&gt; {@link State#TERMINATED}: This occurs 
057     *      when the service successfully stops.</li>
058     * </ul>
059     * 
060     * <p>N.B. The {@link State#FAILED} and {@link State#TERMINATED} states are 
061     * terminal states, once a service enters either of these states it cannot ever 
062     * leave them. 
063     * 
064     * <p>Implementors of this interface are strongly encouraged to extend one of 
065     * the abstract classes in this package which implement this interface and 
066     * make the threading and state management easier.
067     *
068     * @author Jesse Wilson
069     * @since 9.0 (in 1.0 as
070     *     {@code com.google.common.base.Service})
071     */
072    @Beta // TODO(kevinb): make abstract class?
073    public interface Service {
074      /**
075       * If the service state is {@link State#NEW}, this initiates service startup
076       * and returns immediately. If the service has already been started, this
077       * method returns immediately without taking action. A stopped service may not
078       * be restarted.
079       *
080       * @return a future for the startup result, regardless of whether this call
081       *     initiated startup. Calling {@link ListenableFuture#get} will block
082       *     until the service has finished starting, and returns one of {@link
083       *     State#RUNNING}, {@link State#STOPPING} or {@link State#TERMINATED}. If
084       *     the service fails to start, {@link ListenableFuture#get} will throw an
085       *     {@link ExecutionException}, and the service's state will be {@link
086       *     State#FAILED}. If it has already finished starting, {@link
087       *     ListenableFuture#get} returns immediately. Cancelling this future has
088       *     no effect on the service.
089       */
090      ListenableFuture<State> start();
091    
092      /**
093       * Initiates service startup (if necessary), returning once the service has
094       * finished starting. Unlike calling {@code start().get()}, this method throws
095       * no checked exceptions, and it cannot be {@linkplain Thread#interrupt
096       * interrupted}.
097       *
098       * @throws UncheckedExecutionException if startup failed
099       * @return the state of the service when startup finished.
100       */
101      State startAndWait();
102    
103      /**
104       * Returns {@code true} if this service is {@linkplain State#RUNNING running}.
105       */
106      boolean isRunning();
107    
108      /**
109       * Returns the lifecycle state of the service.
110       */
111      State state();
112    
113      /**
114       * If the service is {@linkplain State#STARTING starting} or {@linkplain
115       * State#RUNNING running}, this initiates service shutdown and returns
116       * immediately. If the service is {@linkplain State#NEW new}, it is
117       * {@linkplain State#TERMINATED terminated} without having been started nor
118       * stopped.  If the service has already been stopped, this method returns
119       * immediately without taking action.
120       *
121       * @return a future for the shutdown result, regardless of whether this call
122       *     initiated shutdown. Calling {@link ListenableFuture#get} will block
123       *     until the service has finished shutting down, and either returns
124       *     {@link State#TERMINATED} or throws an {@link ExecutionException}. If
125       *     it has already finished stopping, {@link ListenableFuture#get} returns
126       *     immediately.  Cancelling this future has no effect on the service.
127       */
128      ListenableFuture<State> stop();
129    
130      /**
131       * Initiates service shutdown (if necessary), returning once the service has
132       * finished stopping. If this is {@link State#STARTING}, startup will be
133       * cancelled. If this is {@link State#NEW}, it is {@link State#TERMINATED
134       * terminated} without having been started nor stopped. Unlike calling {@code
135       * stop().get()}, this method throws no checked exceptions.
136       *
137       * @throws UncheckedExecutionException if shutdown failed
138       * @return the state of the service when shutdown finished.
139       */
140      State stopAndWait();
141    
142      /**
143       * The lifecycle states of a service.
144       *
145       * @since 9.0 (in 1.0 as
146       *     {@code com.google.common.base.Service.State})
147       */
148      @Beta // should come out of Beta when Service does
149      enum State {
150        /**
151         * A service in this state is inactive. It does minimal work and consumes
152         * minimal resources.
153         */
154        NEW,
155    
156        /**
157         * A service in this state is transitioning to {@link #RUNNING}.
158         */
159        STARTING,
160    
161        /**
162         * A service in this state is operational.
163         */
164        RUNNING,
165    
166        /**
167         * A service in this state is transitioning to {@link #TERMINATED}.
168         */
169        STOPPING,
170    
171        /**
172         * A service in this state has completed execution normally. It does minimal
173         * work and consumes minimal resources.
174         */
175        TERMINATED,
176    
177        /**
178         * A service in this state has encountered a problem and may not be
179         * operational. It cannot be started nor stopped.
180         */
181        FAILED
182      }
183    }