Coverage Summary for Class: Service (com.google.common.util.concurrent)

Class Method, % Line, %
Service$Listener 0% (0/1) 0% (0/1)
Service$State 0% (0/1) 0% (0/7)
Total 0% (0/2) 0% (0/8)


1 /* 2  * Copyright (C) 2009 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5  * in compliance with the License. You may obtain a copy of the License at 6  * 7  * http://www.apache.org/licenses/LICENSE-2.0 8  * 9  * Unless required by applicable law or agreed to in writing, software distributed under the License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.util.concurrent; 16  17 import static com.google.common.util.concurrent.Internal.toNanosSaturated; 18  19 import com.google.common.annotations.GwtIncompatible; 20 import com.google.errorprone.annotations.CanIgnoreReturnValue; 21 import com.google.errorprone.annotations.DoNotMock; 22 import java.time.Duration; 23 import java.util.concurrent.Executor; 24 import java.util.concurrent.TimeUnit; 25 import java.util.concurrent.TimeoutException; 26  27 /** 28  * An object with an operational state, plus asynchronous {@link #startAsync()} and {@link 29  * #stopAsync()} lifecycle methods to transition between states. Example services include 30  * webservers, RPC servers and timers. 31  * 32  * <p>The normal lifecycle of a service is: 33  * 34  * <ul> 35  * <li>{@linkplain State#NEW NEW} -&gt; 36  * <li>{@linkplain State#STARTING STARTING} -&gt; 37  * <li>{@linkplain State#RUNNING RUNNING} -&gt; 38  * <li>{@linkplain State#STOPPING STOPPING} -&gt; 39  * <li>{@linkplain State#TERMINATED TERMINATED} 40  * </ul> 41  * 42  * <p>There are deviations from this if there are failures or if {@link Service#stopAsync} is called 43  * before the {@link Service} reaches the {@linkplain State#RUNNING RUNNING} state. The set of legal 44  * transitions form a <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">DAG</a>, 45  * therefore every method of the listener will be called at most once. N.B. The {@link State#FAILED} 46  * and {@link State#TERMINATED} states are terminal states, once a service enters either of these 47  * states it cannot ever leave them. 48  * 49  * <p>Implementors of this interface are strongly encouraged to extend one of the abstract classes 50  * in this package which implement this interface and make the threading and state management 51  * easier. 52  * 53  * @author Jesse Wilson 54  * @author Luke Sandberg 55  * @since 9.0 (in 1.0 as {@code com.google.common.base.Service}) 56  */ 57 @DoNotMock("Create an AbstractIdleService") 58 @GwtIncompatible 59 @ElementTypesAreNonnullByDefault 60 public interface Service { 61  /** 62  * If the service state is {@link State#NEW}, this initiates service startup and returns 63  * immediately. A stopped service may not be restarted. 64  * 65  * @return this 66  * @throws IllegalStateException if the service is not {@link State#NEW} 67  * @since 15.0 68  */ 69  @CanIgnoreReturnValue 70  Service startAsync(); 71  72  /** Returns {@code true} if this service is {@linkplain State#RUNNING running}. */ 73  boolean isRunning(); 74  75  /** Returns the lifecycle state of the service. */ 76  State state(); 77  78  /** 79  * If the service is {@linkplain State#STARTING starting} or {@linkplain State#RUNNING running}, 80  * this initiates service shutdown and returns immediately. If the service is {@linkplain 81  * State#NEW new}, it is {@linkplain State#TERMINATED terminated} without having been started nor 82  * stopped. If the service has already been stopped, this method returns immediately without 83  * taking action. 84  * 85  * @return this 86  * @since 15.0 87  */ 88  @CanIgnoreReturnValue 89  Service stopAsync(); 90  91  /** 92  * Waits for the {@link Service} to reach the {@linkplain State#RUNNING running state}. 93  * 94  * @throws IllegalStateException if the service reaches a state from which it is not possible to 95  * enter the {@link State#RUNNING} state. e.g. if the {@code state} is {@code 96  * State#TERMINATED} when this method is called then this will throw an IllegalStateException. 97  * @since 15.0 98  */ 99  void awaitRunning(); 100  101  /** 102  * Waits for the {@link Service} to reach the {@linkplain State#RUNNING running state} for no more 103  * than the given time. 104  * 105  * @param timeout the maximum time to wait 106  * @throws TimeoutException if the service has not reached the given state within the deadline 107  * @throws IllegalStateException if the service reaches a state from which it is not possible to 108  * enter the {@link State#RUNNING RUNNING} state. e.g. if the {@code state} is {@code 109  * State#TERMINATED} when this method is called then this will throw an IllegalStateException. 110  * @since 28.0 111  */ 112  default void awaitRunning(Duration timeout) throws TimeoutException { 113  awaitRunning(toNanosSaturated(timeout), TimeUnit.NANOSECONDS); 114  } 115  116  /** 117  * Waits for the {@link Service} to reach the {@linkplain State#RUNNING running state} for no more 118  * than the given time. 119  * 120  * @param timeout the maximum time to wait 121  * @param unit the time unit of the timeout argument 122  * @throws TimeoutException if the service has not reached the given state within the deadline 123  * @throws IllegalStateException if the service reaches a state from which it is not possible to 124  * enter the {@link State#RUNNING RUNNING} state. e.g. if the {@code state} is {@code 125  * State#TERMINATED} when this method is called then this will throw an IllegalStateException. 126  * @since 15.0 127  */ 128  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 129  void awaitRunning(long timeout, TimeUnit unit) throws TimeoutException; 130  131  /** 132  * Waits for the {@link Service} to reach the {@linkplain State#TERMINATED terminated state}. 133  * 134  * @throws IllegalStateException if the service {@linkplain State#FAILED fails}. 135  * @since 15.0 136  */ 137  void awaitTerminated(); 138  139  /** 140  * Waits for the {@link Service} to reach a terminal state (either {@link Service.State#TERMINATED 141  * terminated} or {@link Service.State#FAILED failed}) for no more than the given time. 142  * 143  * @param timeout the maximum time to wait 144  * @throws TimeoutException if the service has not reached the given state within the deadline 145  * @throws IllegalStateException if the service {@linkplain State#FAILED fails}. 146  * @since 28.0 147  */ 148  default void awaitTerminated(Duration timeout) throws TimeoutException { 149  awaitTerminated(toNanosSaturated(timeout), TimeUnit.NANOSECONDS); 150  } 151  152  /** 153  * Waits for the {@link Service} to reach a terminal state (either {@link Service.State#TERMINATED 154  * terminated} or {@link Service.State#FAILED failed}) for no more than the given time. 155  * 156  * @param timeout the maximum time to wait 157  * @param unit the time unit of the timeout argument 158  * @throws TimeoutException if the service has not reached the given state within the deadline 159  * @throws IllegalStateException if the service {@linkplain State#FAILED fails}. 160  * @since 15.0 161  */ 162  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 163  void awaitTerminated(long timeout, TimeUnit unit) throws TimeoutException; 164  165  /** 166  * Returns the {@link Throwable} that caused this service to fail. 167  * 168  * @throws IllegalStateException if this service's state isn't {@linkplain State#FAILED FAILED}. 169  * @since 14.0 170  */ 171  Throwable failureCause(); 172  173  /** 174  * Registers a {@link Listener} to be {@linkplain Executor#execute executed} on the given 175  * executor. The listener will have the corresponding transition method called whenever the 176  * service changes state. The listener will not have previous state changes replayed, so it is 177  * suggested that listeners are added before the service starts. 178  * 179  * <p>{@code addListener} guarantees execution ordering across calls to a given listener but not 180  * across calls to multiple listeners. Specifically, a given listener will have its callbacks 181  * invoked in the same order as the underlying service enters those states. Additionally, at most 182  * one of the listener's callbacks will execute at once. However, multiple listeners' callbacks 183  * may execute concurrently, and listeners may execute in an order different from the one in which 184  * they were registered. 185  * 186  * <p>RuntimeExceptions thrown by a listener will be caught and logged. Any exception thrown 187  * during {@code Executor.execute} (e.g., a {@code RejectedExecutionException}) will be caught and 188  * logged. 189  * 190  * @param listener the listener to run when the service changes state is complete 191  * @param executor the executor in which the listeners callback methods will be run. For fast, 192  * lightweight listeners that would be safe to execute in any thread, consider {@link 193  * MoreExecutors#directExecutor}. 194  * @since 13.0 195  */ 196  void addListener(Listener listener, Executor executor); 197  198  /** 199  * The lifecycle states of a service. 200  * 201  * <p>The ordering of the {@link State} enum is defined such that if there is a state transition 202  * from {@code A -> B} then {@code A.compareTo(B) < 0}. N.B. The converse is not true, i.e. if 203  * {@code A.compareTo(B) < 0} then there is <b>not</b> guaranteed to be a valid state transition 204  * {@code A -> B}. 205  * 206  * @since 9.0 (in 1.0 as {@code com.google.common.base.Service.State}) 207  */ 208  enum State { 209  /** A service in this state is inactive. It does minimal work and consumes minimal resources. */ 210  NEW, 211  212  /** A service in this state is transitioning to {@link #RUNNING}. */ 213  STARTING, 214  215  /** A service in this state is operational. */ 216  RUNNING, 217  218  /** A service in this state is transitioning to {@link #TERMINATED}. */ 219  STOPPING, 220  221  /** 222  * A service in this state has completed execution normally. It does minimal work and consumes 223  * minimal resources. 224  */ 225  TERMINATED, 226  227  /** 228  * A service in this state has encountered a problem and may not be operational. It cannot be 229  * started nor stopped. 230  */ 231  FAILED, 232  } 233  234  /** 235  * A listener for the various state changes that a {@link Service} goes through in its lifecycle. 236  * 237  * <p>All methods are no-ops by default, implementors should override the ones they care about. 238  * 239  * @author Luke Sandberg 240  * @since 15.0 (present as an interface in 13.0) 241  */ 242  abstract class Listener { 243  /** 244  * Called when the service transitions from {@linkplain State#NEW NEW} to {@linkplain 245  * State#STARTING STARTING}. This occurs when {@link Service#startAsync} is called the first 246  * time. 247  */ 248  public void starting() {} 249  250  /** 251  * Called when the service transitions from {@linkplain State#STARTING STARTING} to {@linkplain 252  * State#RUNNING RUNNING}. This occurs when a service has successfully started. 253  */ 254  public void running() {} 255  256  /** 257  * Called when the service transitions to the {@linkplain State#STOPPING STOPPING} state. The 258  * only valid values for {@code from} are {@linkplain State#STARTING STARTING} or {@linkplain 259  * State#RUNNING RUNNING}. This occurs when {@link Service#stopAsync} is called. 260  * 261  * @param from The previous state that is being transitioned from. 262  */ 263  public void stopping(State from) {} 264  265  /** 266  * Called when the service transitions to the {@linkplain State#TERMINATED TERMINATED} state. 267  * The {@linkplain State#TERMINATED TERMINATED} state is a terminal state in the transition 268  * diagram. Therefore, if this method is called, no other methods will be called on the {@link 269  * Listener}. 270  * 271  * @param from The previous state that is being transitioned from. Failure can occur in any 272  * state with the exception of {@linkplain State#FAILED FAILED} and {@linkplain 273  * State#TERMINATED TERMINATED}. 274  */ 275  public void terminated(State from) {} 276  277  /** 278  * Called when the service transitions to the {@linkplain State#FAILED FAILED} state. The 279  * {@linkplain State#FAILED FAILED} state is a terminal state in the transition diagram. 280  * Therefore, if this method is called, no other methods will be called on the {@link Listener}. 281  * 282  * @param from The previous state that is being transitioned from. Failure can occur in any 283  * state with the exception of {@linkplain State#NEW NEW} or {@linkplain State#TERMINATED 284  * TERMINATED}. 285  * @param failure The exception that caused the failure. 286  */ 287  public void failed(State from, Throwable failure) {} 288  } 289 }