@Override public void sendMessage(ReqT message) { Preconditions.checkState(delegateCall == null, "ThrottlingClientInterceptor only supports unary operations"); Preconditions.checkState(id == null, "ThrottlingClientInterceptor only supports unary operations"); Preconditions.checkState(delegateListener != null, "start() has to be called before sendMessage()."); Preconditions.checkState(headers != null, "start() has to be called before sendMessage()."); try { id = resourceLimiter .registerOperationWithHeapSize(((MessageLite) message).getSerializedSize()); } catch (InterruptedException e) { delegateListener.onClose(Status.INTERNAL.withDescription("Operation was interrupted"), new Metadata()); return; } delegateCall = delegateChannel.newCall(method, callOptions); SimpleForwardingClientCallListener<RespT> markCompletionListener = new SimpleForwardingClientCallListener<RespT>(this.delegateListener) { @Override public void onClose(io.grpc.Status status, Metadata trailers) { resourceLimiter.markCanBeCompleted(id); delegate().onClose(status, trailers); } }; delegate().start(markCompletionListener, headers); delegate().request(numMessagesRequested); delegate().sendMessage(message); }