Refine search
@CanIgnoreReturnValue @Override public final Service stopAsync() { if (monitor.enterIf(isStoppable)) { try { State previous = state(); switch (previous) { case NEW: snapshot = new StateSnapshot(TERMINATED); enqueueTerminatedEvent(NEW); break; case STARTING: snapshot = new StateSnapshot(STARTING, true, null); enqueueStoppingEvent(STARTING); doCancelStart(); break; case RUNNING: snapshot = new StateSnapshot(STOPPING); enqueueStoppingEvent(RUNNING); doStop(); break; case STOPPING: notifyFailed(shutdownFailure); } finally { monitor.leave(); dispatchListenerEvents();
@CanIgnoreReturnValue @Override public final Service startAsync() { if (monitor.enterIf(isStartable)) { try { snapshot = new StateSnapshot(STARTING); enqueueStartingEvent(); doStart(); } catch (Throwable startupFailure) { notifyFailed(startupFailure); } finally { monitor.leave(); dispatchListenerEvents(); } } else { throw new IllegalStateException("Service " + this + " has already been started"); } return this; }
@Override public final boolean isRunning() { return delegate.isRunning(); }
@Override public final void awaitTerminated(long timeout, TimeUnit unit) throws TimeoutException { if (monitor.enterWhenUninterruptibly(isStopped, timeout, unit)) { try { checkCurrentState(TERMINATED); } finally { monitor.leave(); } } else { // It is possible due to races the we are currently in the expected state even though we // timed out. e.g. if we weren't event able to grab the lock within the timeout we would never // even check the guard. I don't think we care too much about this use case but it could lead // to a confusing error message. throw new TimeoutException( "Timed out waiting for " + this + " to reach a terminal state. " + "Current state: " + state()); } }
/** Checks that the current state is equal to the expected state. */ @GuardedBy("monitor") private void checkCurrentState(State expected) { State actual = state(); if (actual != expected) { if (actual == FAILED) { // Handle this specially so that we can include the failureCause, if there is one. throw new IllegalStateException( "Expected the service " + this + " to be " + expected + ", but the service has FAILED", failureCause()); } throw new IllegalStateException( "Expected the service " + this + " to be " + expected + ", but was " + actual); } }
@Deprecated @Override public final ListenableFuture<State> start() { if (monitor.enterIf(isStartable)) { try { snapshot = new StateSnapshot(STARTING); starting(); doStart(); } catch (Throwable startupFailure) { notifyFailed(startupFailure); } finally { monitor.leave(); executeListeners(); } } return startup; }
monitor.enter(); try { new IllegalStateException( "Cannot notifyStarted() when the service is " + snapshot.state); notifyFailed(failure); throw failure; doStop(); } else { snapshot = new StateSnapshot(RUNNING); enqueueRunningEvent(); monitor.leave(); dispatchListenerEvents();
@Override public final void awaitTerminated() { monitor.enterWhenUninterruptibly(isStopped); try { checkCurrentState(TERMINATED); } finally { monitor.leave(); } }
/** * Implementing classes should invoke this method once their service has stopped. It will cause * the service to transition from {@link State#STARTING} or {@link State#STOPPING} to {@link * State#TERMINATED}. * * @throws IllegalStateException if the service is not one of {@link State#STOPPING}, {@link * State#STARTING}, or {@link State#RUNNING}. */ protected final void notifyStopped() { monitor.enter(); try { State previous = state(); switch (previous) { case NEW: case TERMINATED: case FAILED: throw new IllegalStateException("Cannot notifyStopped() when the service is " + previous); case RUNNING: case STARTING: case STOPPING: snapshot = new StateSnapshot(TERMINATED); enqueueTerminatedEvent(previous); break; } } finally { monitor.leave(); dispatchListenerEvents(); } }
/** * Invoke this method to transition the service to the {@link State#FAILED}. The service will * <b>not be stopped</b> if it is running. Invoke this method when a service has failed critically * or otherwise cannot be started nor stopped. */ protected final void notifyFailed(Throwable cause) { checkNotNull(cause); monitor.enter(); try { State previous = state(); switch (previous) { case NEW: case TERMINATED: throw new IllegalStateException("Failed while in state:" + previous, cause); case RUNNING: case STARTING: case STOPPING: snapshot = new StateSnapshot(FAILED, false, cause); enqueueFailedEvent(previous, cause); break; case FAILED: // Do nothing break; } } finally { monitor.leave(); dispatchListenerEvents(); } }
/** * Implementing classes should invoke this method once their service has stopped. It will cause * the service to transition from {@link State#STOPPING} to {@link State#TERMINATED}. * * @throws IllegalStateException if the service is neither {@link State#STOPPING} nor {@link * State#RUNNING}. */ protected final void notifyStopped() { monitor.enter(); try { // We check the internal state of the snapshot instead of state() directly so we don't allow // notifyStopped() to be called while STARTING, even if stop() has already been called. State previous = snapshot.state; if (previous != STOPPING && previous != RUNNING) { IllegalStateException failure = new IllegalStateException("Cannot notifyStopped() when the service is " + previous); notifyFailed(failure); throw failure; } snapshot = new StateSnapshot(TERMINATED); enqueueTerminatedEvent(previous); } finally { monitor.leave(); dispatchListenerEvents(); } }
monitor.enter(); try { IllegalStateException failure = new IllegalStateException( "Cannot notifyStarted() when the service is " + snapshot.state); notifyFailed(failure); throw failure; doStop(); } else { snapshot = new StateSnapshot(RUNNING); running(); monitor.leave(); executeListeners();
@Override public boolean isSatisfied() { return state() == NEW; } }
/** * Implementing classes should invoke this method once their service has started. It will cause * the service to transition from {@link State#STARTING} to {@link State#RUNNING}. * * @throws IllegalStateException if the service is not {@link State#STARTING}. */ protected final void notifyStarted() { lock.lock(); try { if (snapshot.state != State.STARTING) { IllegalStateException failure = new IllegalStateException( "Cannot notifyStarted() when the service is " + snapshot.state); notifyFailed(failure); throw failure; } if (snapshot.shutdownWhenStartupFinishes) { snapshot = new StateSnapshot(State.STOPPING); // We don't call listeners here because we already did that when we set the // shutdownWhenStartupFinishes flag. doStop(); } else { snapshot = new StateSnapshot(State.RUNNING); running(); } } finally { lock.unlock(); executeListeners(); } }
public final Future<State> start() { lock.lock(); try { if (state == State.NEW) { state = State.STARTING; doStart(); } } catch (Throwable startupFailure) { // put the exception in the future, the user can get it via Future.get() notifyFailed(startupFailure); } finally { lock.unlock(); } return startup; }
public final Future<State> stop() { lock.lock(); try { if (state == State.NEW) { state = State.TERMINATED; startup.transitionSucceeded(State.TERMINATED); shutdown.transitionSucceeded(State.TERMINATED); } else if (state == State.STARTING) { shutdownWhenStartupFinishes = true; startup.transitionSucceeded(State.STOPPING); } else if (state == State.RUNNING) { state = State.STOPPING; doStop(); } } catch (Throwable shutdownFailure) { // put the exception in the future, the user can get it via Future.get() notifyFailed(shutdownFailure); } finally { lock.unlock(); } return shutdown; }
/** @since 13.0 */ @Override public final void addListener(Listener listener, Executor executor) { delegate.addListener(listener, executor); }
/** @since 15.0 */ @Override public final void awaitTerminated(long timeout, TimeUnit unit) throws TimeoutException { delegate.awaitTerminated(timeout, unit); }
/** @since 15.0 */ @Override public final void awaitRunning() { delegate.awaitRunning(); }
/** @since 14.0 */ @Override public final Throwable failureCause() { return delegate.failureCause(); }