More information for debugging.

- Include transport information in RPC's final status
- Implement toString() of transports
This commit is contained in:
Kun Zhang 2015-12-30 14:55:05 -08:00
parent fb8532a711
commit eca1f7c1d6
7 changed files with 44 additions and 11 deletions

View File

@ -164,6 +164,11 @@ class InProcessTransport implements ServerTransport, ClientTransport {
} }
} }
@Override
public String toString() {
return getClass().getSimpleName() + "(" + name + ")";
}
private synchronized void notifyShutdown(Status s) { private synchronized void notifyShutdown(Status s) {
if (shutdown) { if (shutdown) {
return; return;

View File

@ -434,7 +434,14 @@ final class ClientCallImpl<ReqT, RespT> extends ClientCall<ReqT, RespT>
trailers = new Metadata(); trailers = new Metadata();
} }
} }
final Status savedStatus = status; ClientTransport transport = null;
try {
transport = transportFuture.get();
} catch (Exception e) {
// Ignore the exception, and keep transport as null.
}
final Status savedStatus = (transport == null
? status : status.augmentDescription("transport=" + transport));
final Metadata savedTrailers = trailers; final Metadata savedTrailers = trailers;
callExecutor.execute(new ContextRunnable(context) { callExecutor.execute(new ContextRunnable(context) {
@Override @Override

View File

@ -158,8 +158,7 @@ public class ManagedChannelImplTest {
ClientCall<String, Integer> call = ClientCall<String, Integer> call =
channel.newCall(method, CallOptions.DEFAULT.withDeadlineNanoTime(System.nanoTime())); channel.newCall(method, CallOptions.DEFAULT.withDeadlineNanoTime(System.nanoTime()));
call.start(mockCallListener, new Metadata()); call.start(mockCallListener, new Metadata());
verify(mockCallListener, timeout(1000)).onClose( verifyListenerClosed(mockCallListener, Status.Code.DEADLINE_EXCEEDED);
same(Status.DEADLINE_EXCEEDED), any(Metadata.class));
} }
@Test @Test
@ -211,7 +210,7 @@ public class ManagedChannelImplTest {
ClientStreamListener streamListener2 = streamListenerCaptor.getValue(); ClientStreamListener streamListener2 = streamListenerCaptor.getValue();
Metadata trailers = new Metadata(); Metadata trailers = new Metadata();
streamListener2.closed(Status.CANCELLED, trailers); streamListener2.closed(Status.CANCELLED, trailers);
verify(mockCallListener2, timeout(1000)).onClose(Status.CANCELLED, trailers); verifyListenerClosed(mockCallListener2, Status.Code.CANCELLED);
// Shutdown // Shutdown
channel.shutdown(); channel.shutdown();
@ -235,7 +234,7 @@ public class ManagedChannelImplTest {
transportListener.transportShutdown(Status.CANCELLED); transportListener.transportShutdown(Status.CANCELLED);
assertFalse(channel.isTerminated()); assertFalse(channel.isTerminated());
streamListener.closed(Status.CANCELLED, trailers); streamListener.closed(Status.CANCELLED, trailers);
verify(mockCallListener, timeout(1000)).onClose(Status.CANCELLED, trailers); verifyListenerClosed(mockCallListener, Status.Code.CANCELLED);
assertFalse(channel.isTerminated()); assertFalse(channel.isTerminated());
transportListener.transportTerminated(); transportListener.transportTerminated();
@ -385,7 +384,7 @@ public class ManagedChannelImplTest {
call.start(mockCallListener, headers); call.start(mockCallListener, headers);
ArgumentCaptor<ClientTransport.Listener> badTransportListenerCaptor = ArgumentCaptor<ClientTransport.Listener> badTransportListenerCaptor =
ArgumentCaptor.forClass(ClientTransport.Listener.class); ArgumentCaptor.forClass(ClientTransport.Listener.class);
verify(mockCallListener, timeout(1000)).onClose(same(Status.UNAVAILABLE), any(Metadata.class)); verifyListenerClosed(mockCallListener, Status.Code.UNAVAILABLE);
verify(badTransport, timeout(1000)).start(badTransportListenerCaptor.capture()); verify(badTransport, timeout(1000)).start(badTransportListenerCaptor.capture());
badTransportListenerCaptor.getValue().transportShutdown(Status.UNAVAILABLE); badTransportListenerCaptor.getValue().transportShutdown(Status.UNAVAILABLE);
@ -396,6 +395,14 @@ public class ManagedChannelImplTest {
same(method), same(headers), any(ClientStreamListener.class)); same(method), same(headers), any(ClientStreamListener.class));
} }
private void verifyListenerClosed(ClientCall.Listener<?> mockCallListener,
Status.Code statusCode) {
ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
verify(mockCallListener, timeout(1000)).onClose(statusCaptor.capture(), any(Metadata.class));
Status status = statusCaptor.getValue();
assertEquals(statusCode, status.getCode());
}
private static class FakeBackoffPolicyProvider implements BackoffPolicy.Provider { private static class FakeBackoffPolicyProvider implements BackoffPolicy.Provider {
@Override @Override
public BackoffPolicy get() { public BackoffPolicy get() {

View File

@ -358,6 +358,7 @@ class GrpclbLoadBalancer extends LoadBalancer {
if (lbResponseObserver != this) { if (lbResponseObserver != this) {
return; return;
} }
logger.info("Received " + status + ", entering fallback mode");
directTransport = transportFuture = Futures.immediateFuture(lbTransport); directTransport = transportFuture = Futures.immediateFuture(lbTransport);
pendingPicksFulfillmentBatch = pendingPicks.createFulfillmentBatch(); pendingPicksFulfillmentBatch = pendingPicks.createFulfillmentBatch();
} }

View File

@ -338,7 +338,8 @@ public abstract class AbstractTransportTest {
requestObserver.onError(new RuntimeException()); requestObserver.onError(new RuntimeException());
responseObserver.awaitCompletion(); responseObserver.awaitCompletion();
assertEquals(Arrays.<StreamingInputCallResponse>asList(), responseObserver.getValues()); assertEquals(Arrays.<StreamingInputCallResponse>asList(), responseObserver.getValues());
assertEquals(Status.CANCELLED, Status.fromThrowable(responseObserver.getError())); assertEquals(Status.Code.CANCELLED,
Status.fromThrowable(responseObserver.getError()).getCode());
} }
@Test(timeout = 10000) @Test(timeout = 10000)
@ -366,7 +367,7 @@ public abstract class AbstractTransportTest {
requestObserver.onError(new RuntimeException()); requestObserver.onError(new RuntimeException());
ArgumentCaptor<Throwable> captor = ArgumentCaptor.forClass(Throwable.class); ArgumentCaptor<Throwable> captor = ArgumentCaptor.forClass(Throwable.class);
verify(responseObserver, timeout(OPERATION_TIMEOUT)).onError(captor.capture()); verify(responseObserver, timeout(OPERATION_TIMEOUT)).onError(captor.capture());
assertEquals(Status.CANCELLED, Status.fromThrowable(captor.getValue())); assertEquals(Status.Code.CANCELLED, Status.fromThrowable(captor.getValue()).getCode());
verifyNoMoreInteractions(responseObserver); verifyNoMoreInteractions(responseObserver);
} }
@ -489,7 +490,8 @@ public abstract class AbstractTransportTest {
// Make sure that everything still completes. // Make sure that everything still completes.
call.request(1); call.request(1);
assertEquals(goldenResponses.get(1), queue.poll(OPERATION_TIMEOUT, TimeUnit.MILLISECONDS)); assertEquals(goldenResponses.get(1), queue.poll(OPERATION_TIMEOUT, TimeUnit.MILLISECONDS));
assertEquals(Status.OK, queue.poll(OPERATION_TIMEOUT, TimeUnit.MILLISECONDS)); assertEquals(Status.Code.OK,
((Status) queue.poll(OPERATION_TIMEOUT, TimeUnit.MILLISECONDS)).getCode());
} }
@Test(timeout = 30000) @Test(timeout = 30000)
@ -632,7 +634,7 @@ public abstract class AbstractTransportTest {
.build()).next(); .build()).next();
fail("Expected deadline to be exceeded"); fail("Expected deadline to be exceeded");
} catch (Throwable t) { } catch (Throwable t) {
assertEquals(Status.DEADLINE_EXCEEDED, Status.fromThrowable(t)); assertEquals(Status.Code.DEADLINE_EXCEEDED, Status.fromThrowable(t).getCode());
} }
} }
@ -655,7 +657,8 @@ public abstract class AbstractTransportTest {
.withDeadlineAfter(30, TimeUnit.MILLISECONDS) .withDeadlineAfter(30, TimeUnit.MILLISECONDS)
.streamingOutputCall(request, recorder); .streamingOutputCall(request, recorder);
recorder.awaitCompletion(); recorder.awaitCompletion();
assertEquals(Status.DEADLINE_EXCEEDED, Status.fromThrowable(recorder.getError())); assertEquals(Status.Code.DEADLINE_EXCEEDED,
Status.fromThrowable(recorder.getError()).getCode());
} }
protected int unaryPayloadLength() { protected int unaryPayloadLength() {

View File

@ -212,6 +212,11 @@ class NettyClientTransport implements ClientTransport {
} }
} }
@Override
public String toString() {
return getClass().getSimpleName() + "(" + address + ")";
}
private void notifyShutdown(Status status) { private void notifyShutdown(Status status) {
Preconditions.checkNotNull(status, "status"); Preconditions.checkNotNull(status, "status");
boolean notifyShutdown; boolean notifyShutdown;

View File

@ -404,6 +404,11 @@ class OkHttpClientTransport implements ClientTransport {
}); });
} }
@Override
public String toString() {
return getClass().getSimpleName() + "(" + address + ")";
}
/** /**
* Gets the overriden authority hostname. If the authority is overriden to be an invalid * Gets the overriden authority hostname. If the authority is overriden to be an invalid
* authority, uri.getHost() will (rightly) return null, since the authority is no longer * authority, uri.getHost() will (rightly) return null, since the authority is no longer