下面列出了怎么用com.google.common.util.concurrent.Service.State的API类实例代码及写法,或者点击链接到github查看源代码。
StateSnapshot(
State internalState, boolean shutdownWhenStartupFinishes, @Nullable Throwable failure) {
checkArgument(
!shutdownWhenStartupFinishes || internalState == STARTING,
"shudownWhenStartupFinishes can only be set if state is STARTING. Got %s instead.",
internalState);
checkArgument(
!(failure != null ^ internalState == FAILED),
"A failure cause should be set if and only if the state is failed. Got %s and %s "
+ "instead.",
internalState,
failure);
this.state = internalState;
this.shutdownWhenStartupFinishes = shutdownWhenStartupFinishes;
this.failure = failure;
}
@Test
public void testStartAndStop() throws GeneralSecurityException, IOException {
BatchRequestService batchRequestService =
new BatchRequestService.Builder(service)
.setGoogleCredential(credentialFactory.getCredential(Collections.emptyList()))
.build();
UsersServiceImpl usersService =
new UsersServiceImpl.Builder()
.setBatchRequestService(batchRequestService)
.setCredentialFactory(credentialFactory)
.setCustomer("c1")
.setBatchPolicy(BatchPolicy.fromConfiguration())
.build();
usersService.startAsync().awaitRunning();
assertTrue(batchRequestService.isRunning());
usersService.stopAsync().awaitTerminated();
assertEquals(State.TERMINATED, batchRequestService.state());
}
@Test
public void testRun_writesMetrics() throws Exception {
Optional<ImmutableList<MetricPoint<?>>> threeBatch =
Optional.of(ImmutableList.of(point, point, point));
exporter.startAsync();
insertAndAssert(threeBatch);
// Insert another batch in order to block until the exporter has processed the last one
insertAndAssert(threeBatch);
// Force the exporter to finish so that the verify counts below are deterministic
insertAndAssert(poisonPill);
try {
exporter.awaitTerminated(500, TimeUnit.MILLISECONDS);
} catch (TimeoutException timeout) {
fail("MetricExporter did not reach the TERMINATED state after receiving a poison pill");
}
assertThat(exporter.state()).isNotEqualTo(State.FAILED);
verify(writer, times(6)).write(point);
verify(writer, times(2)).flush();
}
@Override
public void failed(State from, Throwable failure) {
ServiceManagerState state = this.state.get();
if (state != null) {
// Log before the transition, so that if the process exits in response to server failure,
// there is a higher likelihood that the cause will be in the logs.
boolean log = !(service instanceof NoOpService);
if (log) {
logger.log(
Level.SEVERE,
"Service " + service + " has failed in the " + from + " state.",
failure);
}
state.transitionService(service, from, FAILED);
}
}
/**
* 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);
terminated(previous);
} finally {
monitor.leave();
executeListeners();
}
}
@GuardedBy("monitor")
private void terminated(final State from) {
switch (from) {
case NEW:
TERMINATED_FROM_NEW_CALLBACK.enqueueOn(listeners);
break;
case RUNNING:
TERMINATED_FROM_RUNNING_CALLBACK.enqueueOn(listeners);
break;
case STOPPING:
TERMINATED_FROM_STOPPING_CALLBACK.enqueueOn(listeners);
break;
case STARTING:
case TERMINATED:
case FAILED:
default:
throw new AssertionError();
}
}
/**
* 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);
terminated(previous);
} finally {
monitor.leave();
executeListeners();
}
}
@GuardedBy("monitor")
private void terminated(final State from) {
switch (from) {
case NEW:
TERMINATED_FROM_NEW_CALLBACK.enqueueOn(listeners);
break;
case RUNNING:
TERMINATED_FROM_RUNNING_CALLBACK.enqueueOn(listeners);
break;
case STOPPING:
TERMINATED_FROM_STOPPING_CALLBACK.enqueueOn(listeners);
break;
case STARTING:
case TERMINATED:
case FAILED:
default:
throw new AssertionError();
}
}
@GuardedBy("monitor")
private void terminated(final State from) {
switch (from) {
case NEW:
TERMINATED_FROM_NEW_CALLBACK.enqueueOn(listeners);
break;
case RUNNING:
TERMINATED_FROM_RUNNING_CALLBACK.enqueueOn(listeners);
break;
case STOPPING:
TERMINATED_FROM_STOPPING_CALLBACK.enqueueOn(listeners);
break;
case STARTING:
case TERMINATED:
case FAILED:
default:
throw new AssertionError();
}
}
@GuardedBy("monitor")
private void terminated(final State from) {
switch (from) {
case NEW:
TERMINATED_FROM_NEW_CALLBACK.enqueueOn(listeners);
break;
case RUNNING:
TERMINATED_FROM_RUNNING_CALLBACK.enqueueOn(listeners);
break;
case STOPPING:
TERMINATED_FROM_STOPPING_CALLBACK.enqueueOn(listeners);
break;
case STARTING:
case TERMINATED:
case FAILED:
default:
throw new AssertionError();
}
}
private static void validateStartError(
IndexingApplication subject, Class<? extends Exception> causeType, String errorMessage)
throws InterruptedException {
try {
subject.start();
} catch (IllegalStateException e) {
validateStartFailure(e, causeType, errorMessage);
return;
} finally {
assertEquals(State.FAILED, subject.state());
}
// missed expected exception
fail(causeType + " was expected");
}
private static void validateStartError(Application subject, Class<? extends Exception> causeType)
throws InterruptedException {
try {
subject.start();
} catch (IllegalStateException e) {
validateStartFailure(e, causeType);
return;
} finally {
assertEquals(State.FAILED, subject.state());
}
// missed expected exception
fail(causeType + " was expected");
}
private static void validateStartError(
IdentityApplication subject, Class<? extends Exception> causeType)
throws InterruptedException {
try {
subject.start();
} catch (IllegalStateException e) {
validateStartFailure(e, causeType);
return;
} finally {
assertEquals(State.FAILED, subject.state());
}
// missed expected exception
fail(causeType + " was expected");
}
private static Callback<Listener> terminatedCallback(final State from) {
return new Callback<Listener>("terminated({from = " + from + "})") {
@Override
void call(Listener listener) {
listener.terminated(from);
}
};
}
@Override
public void stopping(State from) {
ServiceManagerState state = this.state.get();
if (state != null) {
state.transitionService(service, from, STOPPING);
}
}
@Override
public void failed(State from, Throwable failure) {
ServiceManagerState state = this.state.get();
if (state != null) {
// Log before the transition, so that if the process exits in response to server failure,
// there is a higher likelihood that the cause will be in the logs.
boolean log = !(service instanceof NoOpService);
if (log) {
logger.log(Level.SEVERE,
"Service " + service + " has failed in the " + from + " state.", failure);
}
state.transitionService(service, from, FAILED);
}
}
@Test
public void testRun_terminates_afterPoisonPill() throws Exception {
exporter.startAsync().awaitRunning();
insertAndAssert(poisonPill);
try {
exporter.awaitTerminated(500, TimeUnit.MILLISECONDS);
} catch (TimeoutException timeout) {
fail("MetricExporter did not reach the TERMINATED state after receiving a poison pill");
}
assertThat(exporter.state()).isEqualTo(State.TERMINATED);
}
@Test
public void testRun_staysRunning_afterIOException() throws Exception {
Optional<ImmutableList<MetricPoint<?>>> threeBatch =
Optional.of(ImmutableList.of(point, point, point));
doThrow(new IOException()).when(writer).write(Matchers.<MetricPoint<?>>any());
exporter.startAsync();
insertAndAssert(threeBatch);
// Insert another batch in order to block until the exporter has processed the last one
insertAndAssert(threeBatch);
// Insert another to make sure the exporter hasn't gotten stuck
insertAndAssert(threeBatch);
assertThat(exporter.state()).isNotEqualTo(State.FAILED);
}
public void shutdown() {
GuiceDI.getInstance(ServerRegistry.class).stopAsync();
GuiceDI.getInstance(RemotingNettyServer.class).stopAsync().addListener(new Listener() {
@Override
public void terminated(State from) {
super.terminated(from);
logger.info("zk registry stopped");
}
}, MoreExecutors.directExecutor());
}
public void initilializeCustomEvictor() {
LogWriterI18n logger = getSystem().getLogWriter().convertToLogWriterI18n();
if (getCustomEvictionAttributes() != null
&& !getCustomEvictionAttributes().isEvictIncoming()) {
State st = getEvictorTask().startAndWait();
if (st != State.RUNNING) {
if (logger.fineEnabled()) {
logger.fine(" The Evictor Service failed to start.");
}
}
if (logger.fineEnabled()) {
logger.fine(" The Evictor Service started and its state is " + st);
}
}
}
private static Callback<Listener> terminatedCallback(final State from) {
return new Callback<Listener>("terminated({from = " + from + "})") {
@Override
void call(Listener listener) {
listener.terminated(from);
}
};
}
private static Callback<Listener> stoppingCallback(final State from) {
return new Callback<Listener>("stopping({from = " + from + "})") {
@Override
void call(Listener listener) {
listener.stopping(from);
}
};
}
/** 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);
}
}
/**
* 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);
failed(previous, cause);
break;
case FAILED:
// Do nothing
break;
default:
throw new AssertionError("Unexpected state: " + previous);
}
} finally {
monitor.leave();
executeListeners();
}
}
@Override
public void terminated(State from) {
ServiceManagerState state = this.state.get();
if (state != null) {
if (!(service instanceof NoOpService)) {
logger.log(
Level.FINE,
"Service {0} has terminated. Previous state was: {1}",
new Object[] {service, from});
}
state.transitionService(service, from, TERMINATED);
}
}
@GuardedBy("monitor")
private void failed(final State from, final Throwable cause) {
// can't memoize this one due to the exception
new Callback<Listener>("failed({from = " + from + ", cause = " + cause + "})") {
@Override
void call(Listener listener) {
listener.failed(from, cause);
}
}.enqueueOn(listeners);
}
StateSnapshot(State internalState, boolean shutdownWhenStartupFinishes, @Nullable Throwable failure) {
checkArgument(!shutdownWhenStartupFinishes || internalState == STARTING, "shudownWhenStartupFinishes can only be set if state is STARTING. Got %s instead.", internalState);
checkArgument(!(failure != null ^ internalState == FAILED),
"A failure cause should be set if and only if the state is failed. Got %s and %s "
+ "instead.", internalState, failure);
this.state = internalState;
this.shutdownWhenStartupFinishes = shutdownWhenStartupFinishes;
this.failure = failure;
}
StateSnapshot(State internalState, boolean shutdownWhenStartupFinishes, @Nullable Throwable failure) {
checkArgument(!shutdownWhenStartupFinishes || internalState == STARTING, "shudownWhenStartupFinishes can only be set if state is STARTING. Got %s instead.", internalState);
checkArgument(!(failure != null ^ internalState == FAILED),
"A failure cause should be set if and only if the state is failed. Got %s and %s "
+ "instead.", internalState, failure);
this.state = internalState;
this.shutdownWhenStartupFinishes = shutdownWhenStartupFinishes;
this.failure = failure;
}
ImmutableMultimap<State, Service> servicesByState() {
ImmutableSetMultimap.Builder<State, Service> builder = ImmutableSetMultimap.builder();
monitor.enter();
try {
for (Entry<State, Service> entry : servicesByState.entries()) {
if (!(entry.getValue() instanceof NoOpService)) {
builder.put(entry);
}
}
} finally {
monitor.leave();
}
return builder.build();
}
@Override
public void stopping(State from) {
ServiceManagerState state = this.state.get();
if (state != null) {
state.transitionService(service, from, STOPPING);
}
}