code: public ResT receive(long timeoutMs) throws IOException {
      if (mCompleted) {
        return null;
      }
      if (mCanceled) {
        throw new CancelledException(formatErrorMessage("Stream is already canceled."));
      }
      try {
        Object response = mResponses.poll(timeoutMs, TimeUnit.MILLISECONDS);
        if (response == null) {
          throw new DeadlineExceededException(
              formatErrorMessage("Timeout waiting for response after %dms.", timeoutMs));
        }
        if (response == mResponseObserver) {
          mCompleted = true;
          return null;
        }
        checkError();
        return (ResT) response;
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new CancelledException(
            formatErrorMessage("Interrupted while waiting for response."), e);
      }
    }
docs: Receives a response from the server. Will wait until a response is received, or
  throw an exception if times out.
  
  @param timeoutMs maximum time to wait before giving up and throwing
  a {@link DeadlineExceededException}
  @return the response message, or null if the inbound stream is completed
  @throws IOException if any error occurs