protected void submitRequest(RestRequest restRequest, RestResponseChannel restResponseChannel)
      throws RestServiceException {
    long processingStartTime = System.currentTimeMillis();
    if (restRequest == null || restResponseChannel == null) {
      throw new IllegalArgumentException("Received one or more null arguments");
    }
    restRequest.getMetricsTracker().scalingMetricsTracker.markRequestReceived();
    metrics.requestArrivalRate.mark();
    try {
      logger.trace("Queuing request {}", restRequest.getUri());
      AsyncRequestInfo requestInfo = new AsyncRequestInfo(restRequest, restResponseChannel);
      boolean added = false;
      RestServiceException exception = null;
      try {
        added = requests.add(requestInfo);
      } catch (Exception e) {
        exception = new RestServiceException("Attempt to add request failed", e,
            RestServiceErrorCode.RequestResponseQueuingFailure);
      }
      if (added) {
        queuedRequestCount.incrementAndGet();
        logger.trace("Queued request {}", restRequest.getUri());
        metrics.requestQueuingRate.mark();
      } else {
        metrics.requestQueueAddError.inc();
        if (exception == null) {
          exception = new RestServiceException("Attempt to add request failed",
              RestServiceErrorCode.RequestResponseQueuingFailure);
        }
        throw exception;
      }
    } finally {
      long preProcessingTime = System.currentTimeMillis() - processingStartTime;
      metrics.requestPreProcessingTimeInMs.update(preProcessingTime);
      restRequest.getMetricsTracker().scalingMetricsTracker.addToRequestProcessingTime(preProcessingTime);
    }
  }
Queues the {@code restRequest} to be handled async. When this function returns, it may not be handled yet.
@param restRequest the {@link RestRequest} that needs to be handled.
@param restResponseChannel the {@link RestResponseChannel} on which a response to the request may be sent.
@throws IllegalArgumentException if either of {@code restRequest} or {@code restResponseChannel} is null.
@throws RestServiceException if the service is unavailable or if there is a problem queuing the request.
ambry-rest/src/main/java/com/github/ambry/rest/AsyncRequestResponseHandler.java