stub: Use named classes rather than anonymous in ServerCalls

This has a number of small benefits.  First, it makes stack traces
easier to read.  For example:

Old class names:
```
ServerCalls$1$1.class
ServerCalls$1.class
ServerCalls$2$1.class
ServerCalls$2.class
```

New class names:
```
ServerCalls$StreamingServerCallHandler.class
ServerCalls$StreamingServerCallHandler$StreamingServerCallListener.class
ServerCalls$UnaryServerCallHandler.class
ServerCalls$UnaryServerCallHandler$UnaryServerCallListener.class
```

This is much easier to read quickly, espcially if line numbers don't
match between HEAD and the code that prints the stack trace.

Another benefit of this is that it drops a class file from the jar
(`EmptyServerCallListener`).

Lastly, it makes it easier in the future to test, since the specific
class can be referenced from a test.  Traditionally this class
hasn't been easy to test.
This commit is contained in:
Carl Mastrangelo 2017-07-13 14:33:25 -07:00 committed by GitHub
parent 26caa488a5
commit d387bfe72f
1 changed files with 168 additions and 138 deletions

View File

@ -104,30 +104,44 @@ public final class ServerCalls {
extends StreamingRequestMethod<ReqT, RespT> { extends StreamingRequestMethod<ReqT, RespT> {
} }
/** private static final class UnaryServerCallHandler<ReqT, RespT>
* Creates a {@code ServerCallHandler} for a unary request call method of the service. implements ServerCallHandler<ReqT, RespT> {
*
* @param method an adaptor to the actual method on the service implementation. private final UnaryRequestMethod<ReqT, RespT> method;
*/
private static <ReqT, RespT> ServerCallHandler<ReqT, RespT> asyncUnaryRequestCall( // Non private to avoid synthetic class
final UnaryRequestMethod<ReqT, RespT> method) { UnaryServerCallHandler(UnaryRequestMethod<ReqT, RespT> method) {
return new ServerCallHandler<ReqT, RespT>() { this.method = method;
}
@Override @Override
public ServerCall.Listener<ReqT> startCall( public ServerCall.Listener<ReqT> startCall(ServerCall<ReqT, RespT> call, Metadata headers) {
final ServerCall<ReqT, RespT> call,
Metadata headers) {
Preconditions.checkArgument( Preconditions.checkArgument(
call.getMethodDescriptor().getType().clientSendsOneMessage(), call.getMethodDescriptor().getType().clientSendsOneMessage(),
"asyncUnaryRequestCall is only for clientSendsOneMessage methods"); "asyncUnaryRequestCall is only for clientSendsOneMessage methods");
final ServerCallStreamObserverImpl<ReqT, RespT> responseObserver = ServerCallStreamObserverImpl<ReqT, RespT> responseObserver =
new ServerCallStreamObserverImpl<ReqT, RespT>(call); new ServerCallStreamObserverImpl<ReqT, RespT>(call);
// We expect only 1 request, but we ask for 2 requests here so that if a misbehaving client // We expect only 1 request, but we ask for 2 requests here so that if a misbehaving client
// sends more than 1 requests, ServerCall will catch it. Note that disabling auto // sends more than 1 requests, ServerCall will catch it. Note that disabling auto
// inbound flow control has no effect on unary calls. // inbound flow control has no effect on unary calls.
call.request(2); call.request(2);
return new EmptyServerCallListener<ReqT>() { return new UnaryServerCallListener(responseObserver, call);
boolean canInvoke = true; }
ReqT request;
private final class UnaryServerCallListener extends ServerCall.Listener<ReqT> {
private final ServerCall<ReqT, RespT> call;
private final ServerCallStreamObserverImpl<ReqT, RespT> responseObserver;
private boolean canInvoke = true;
private ReqT request;
// Non private to avoid synthetic class
UnaryServerCallListener(
ServerCallStreamObserverImpl<ReqT, RespT> responseObserver,
ServerCall<ReqT, RespT> call) {
this.call = call;
this.responseObserver = responseObserver;
}
@Override @Override
public void onMessage(ReqT request) { public void onMessage(ReqT request) {
if (this.request != null) { if (this.request != null) {
@ -180,32 +194,57 @@ public final class ServerCalls {
responseObserver.onReadyHandler.run(); responseObserver.onReadyHandler.run();
} }
} }
};
} }
};
} }
/** /**
* Creates a {@code ServerCallHandler} for a streaming request call method of the service. * Creates a {@code ServerCallHandler} for a unary request call method of the service.
* *
* @param method an adaptor to the actual method on the service implementation. * @param method an adaptor to the actual method on the service implementation.
*/ */
private static <ReqT, RespT> ServerCallHandler<ReqT, RespT> asyncStreamingRequestCall( private static <ReqT, RespT> ServerCallHandler<ReqT, RespT> asyncUnaryRequestCall(
final StreamingRequestMethod<ReqT, RespT> method) { UnaryRequestMethod<ReqT, RespT> method) {
return new ServerCallHandler<ReqT, RespT>() { return new UnaryServerCallHandler<ReqT, RespT>(method);
}
private static final class StreamingServerCallHandler<ReqT, RespT>
implements ServerCallHandler<ReqT, RespT> {
private final StreamingRequestMethod<ReqT, RespT> method;
// Non private to avoid synthetic class
StreamingServerCallHandler(StreamingRequestMethod<ReqT, RespT> method) {
this.method = method;
}
@Override @Override
public ServerCall.Listener<ReqT> startCall( public ServerCall.Listener<ReqT> startCall(ServerCall<ReqT, RespT> call, Metadata headers) {
final ServerCall<ReqT, RespT> call, ServerCallStreamObserverImpl<ReqT, RespT> responseObserver =
Metadata headers) {
final ServerCallStreamObserverImpl<ReqT, RespT> responseObserver =
new ServerCallStreamObserverImpl<ReqT, RespT>(call); new ServerCallStreamObserverImpl<ReqT, RespT>(call);
final StreamObserver<ReqT> requestObserver = method.invoke(responseObserver); StreamObserver<ReqT> requestObserver = method.invoke(responseObserver);
responseObserver.freeze(); responseObserver.freeze();
if (responseObserver.autoFlowControlEnabled) { if (responseObserver.autoFlowControlEnabled) {
call.request(1); call.request(1);
} }
return new EmptyServerCallListener<ReqT>() { return new StreamingServerCallListener(requestObserver, responseObserver, call);
boolean halfClosed = false; }
private final class StreamingServerCallListener extends ServerCall.Listener<ReqT> {
private final StreamObserver<ReqT> requestObserver;
private final ServerCallStreamObserverImpl<ReqT, RespT> responseObserver;
private final ServerCall<ReqT, RespT> call;
private boolean halfClosed = false;
// Non private to avoid synthetic class
StreamingServerCallListener(
StreamObserver<ReqT> requestObserver,
ServerCallStreamObserverImpl<ReqT, RespT> responseObserver,
ServerCall<ReqT, RespT> call) {
this.requestObserver = requestObserver;
this.responseObserver = responseObserver;
this.call = call;
}
@Override @Override
public void onMessage(ReqT request) { public void onMessage(ReqT request) {
@ -240,9 +279,17 @@ public final class ServerCalls {
responseObserver.onReadyHandler.run(); responseObserver.onReadyHandler.run();
} }
} }
};
} }
}; }
/**
* Creates a {@code ServerCallHandler} for a streaming request call method of the service.
*
* @param method an adaptor to the actual method on the service implementation.
*/
private static <ReqT, RespT> ServerCallHandler<ReqT, RespT> asyncStreamingRequestCall(
StreamingRequestMethod<ReqT, RespT> method) {
return new StreamingServerCallHandler<ReqT, RespT>(method);
} }
private static interface UnaryRequestMethod<ReqT, RespT> { private static interface UnaryRequestMethod<ReqT, RespT> {
@ -263,6 +310,7 @@ public final class ServerCalls {
private Runnable onReadyHandler; private Runnable onReadyHandler;
private Runnable onCancelHandler; private Runnable onCancelHandler;
// Non private to avoid synthetic class
ServerCallStreamObserverImpl(ServerCall<ReqT, RespT> call) { ServerCallStreamObserverImpl(ServerCall<ReqT, RespT> call) {
this.call = call; this.call = call;
} }
@ -352,24 +400,6 @@ public final class ServerCalls {
} }
} }
private static class EmptyServerCallListener<ReqT> extends ServerCall.Listener<ReqT> {
@Override
public void onMessage(ReqT request) {
}
@Override
public void onHalfClose() {
}
@Override
public void onCancel() {
}
@Override
public void onComplete() {
}
}
/** /**
* Sets unimplemented status for method on given response stream for unary call. * Sets unimplemented status for method on given response stream for unary call.
* *