Skip to content

Instantly share code, notes, and snippets.

@nsivabalan
Last active October 28, 2020 19:51
Show Gist options
  • Save nsivabalan/997dd3d124834219692e068ceba4fd54 to your computer and use it in GitHub Desktop.
Save nsivabalan/997dd3d124834219692e068ceba4fd54 to your computer and use it in GitHub Desktop.
/**
* Callbacks for receiving headers, response messages and completion status from the server.
*
* <p>Implementations are free to block for extended periods of time. Implementations are not
* required to be thread-safe.
*
* <p>This exactly mimics {@link io.grpc.ClientCall.Listener} with Uber specific entities. This will
* also act as a wrapper for grpc's {@link ClientCall.Listener} in Adaptor/ grpc translations
* layers.
*
* @param <RespT> represents response of generic type RespT.
*/
public class UberCallListener<RespT> {
@Nullable private ClientCall.Listener listener;
public UberCallListener() {}
public UberCallListener(ClientCall.Listener listener) {
this.listener = listener;
}
/**
* The response headers have been received. Headers always precede messages.
*
* @param headers containing metadata sent by the server at the start of the response.
*/
public void onHeaders(UberNetworkHeaders headers) {
if (listener != null) {
listener.onHeaders((Metadata) headers.getNetworkTransportHeaders());
}
}
/**
* A response message has been received. May be called zero or more times depending on whether the
* call response is empty, a single message or a stream of messages.
*
* @param message returned by the server
*/
public void onMessage(RespT message) {
if (listener != null) {
listener.onMessage(message);
}
}
/**
* The UberClientCall has been closed. Any additional calls to the {@code UberClientCall} will not
* be processed by the server. No further receiving will occur and no further notifications will
* be made.
*
* <p>If {@code status} returns false for {@link UberNetworkRequestStatus#isSuccess()} ()}, then
* the call failed. An additional block of trailer {@link UberNetworkHeaders} may be received at
* the end of the call from the server. An empty {@link Metadata} UberNetworkHeaders is passed if
* no trailers are received.
*
* @param status the result of the remote call.
* @param trailers UberNetworkHeaders provided at call completion.
*/
public void onClose(UberNetworkRequestStatus status, UberNetworkHeaders trailers) {
if (listener != null) {
listener.onClose(
(io.grpc.Status) status.getNetworkTransportStatus(),
(Metadata) trailers.getNetworkTransportHeaders());
}
}
/**
* This indicates that the UberClientCall may now be capable of sending additional messages (via
* {@link UberClientCall#sendMessage}) without requiring excessive buffering internally. This
* event is just a suggestion and the application is free to ignore it, however doing so may
* result in excessive buffering within the UberClientCall.
*
* <p>Because there is a processing delay to deliver this notification, it is possible for
* concurrent writes to cause {@code isReady() == false} within this callback. Handle "spurious"
* notifications by checking {@code isReady()}'s current value instead of assuming it is now
* {@code true}. If {@code isReady() == false} the normal expectations apply, so there would be
* <em>another</em> {@code onReady()} callback.
*
* <p>If the type of a call is either {@link MethodType#UNARY} or {@link
* MethodType#SERVER_STREAMING}, this callback may not be fired. Calls that send exactly one
* message should not await this callback.
*/
public void onReady() {
if (listener != null) {
listener.onReady();
}
}
/** @return Grpc listener if present. */
@Nullable
public ClientCall.Listener getGrpcListener() {
return listener;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment