core: fix ConnectivityStateManager is already disabled bug

This commit is contained in:
ZHANG Dapeng 2017-08-01 10:26:02 -07:00 committed by GitHub
parent c0e010af8f
commit 18970e6ef3
3 changed files with 56 additions and 2 deletions

View File

@ -63,7 +63,7 @@ final class ConnectivityStateManager {
*/ */
void gotoState(@Nonnull ConnectivityState newState) { void gotoState(@Nonnull ConnectivityState newState) {
checkNotNull(newState, "newState"); checkNotNull(newState, "newState");
checkState(state != null, "ConnectivityStateManager is already disabled"); checkState(!isDisabled(), "ConnectivityStateManager is already disabled");
gotoNullableState(newState); gotoNullableState(newState);
} }
@ -102,6 +102,13 @@ final class ConnectivityStateManager {
gotoNullableState(null); gotoNullableState(null);
} }
/**
* This method is threadsafe.
*/
boolean isDisabled() {
return state == null;
}
private static final class Listener { private static final class Listener {
final Runnable callback; final Runnable callback;
final Executor executor; final Executor executor;

View File

@ -462,8 +462,10 @@ public final class ManagedChannelImpl extends ManagedChannel implements WithLogI
channelExecutor.executeLater(new Runnable() { channelExecutor.executeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
if (!channelStateManager.isDisabled()) {
channelStateManager.gotoState(SHUTDOWN); channelStateManager.gotoState(SHUTDOWN);
} }
}
}); });
delayedTransport.shutdown(); delayedTransport.shutdown();

View File

@ -17,12 +17,15 @@
package io.grpc.internal; package io.grpc.internal;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.MoreExecutors;
import io.grpc.ConnectivityState; import io.grpc.ConnectivityState;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.JUnit4; import org.junit.runners.JUnit4;
@ -31,6 +34,9 @@ import org.junit.runners.JUnit4;
*/ */
@RunWith(JUnit4.class) @RunWith(JUnit4.class)
public class ConnectivityStateManagerTest { public class ConnectivityStateManagerTest {
@Rule
public final ExpectedException thrown = ExpectedException.none();
private final FakeClock executor = new FakeClock(); private final FakeClock executor = new FakeClock();
private final ConnectivityStateManager state = new ConnectivityStateManager(); private final ConnectivityStateManager state = new ConnectivityStateManager();
private final LinkedList<ConnectivityState> sink = new LinkedList<ConnectivityState>(); private final LinkedList<ConnectivityState> sink = new LinkedList<ConnectivityState>();
@ -223,4 +229,43 @@ public class ConnectivityStateManagerTest {
assertEquals(1, sink.size()); assertEquals(1, sink.size());
assertEquals(ConnectivityState.READY, sink.poll()); assertEquals(ConnectivityState.READY, sink.poll());
} }
@Test
public void disable() {
state.disable();
assertTrue(state.isDisabled());
thrown.expect(UnsupportedOperationException.class);
thrown.expectMessage("Channel state API is not implemented");
state.getState();
}
@Test
public void disableThenDisable() {
state.disable();
state.disable();
assertTrue(state.isDisabled());
thrown.expect(UnsupportedOperationException.class);
thrown.expectMessage("Channel state API is not implemented");
state.getState();
}
@Test
public void disableThenGotoReady() {
state.disable();
thrown.expect(IllegalStateException.class);
thrown.expectMessage("ConnectivityStateManager is already disabled");
state.gotoState(ConnectivityState.READY);
}
@Test
public void shutdownThenReady() {
state.gotoState(ConnectivityState.SHUTDOWN);
assertEquals(ConnectivityState.SHUTDOWN, state.getState());
state.gotoState(ConnectivityState.READY);
assertEquals(ConnectivityState.SHUTDOWN, state.getState());
}
} }