code: private <T> Task<Response<T>> createTaskWithD2Timeout(final String name, final Request<T> request,
        final RequestContext requestContext, RequestConfig config) {
      ConfigValue<Long> timeout = config.getTimeoutMs();
      boolean taskNeedTimeout = needApplyTaskTimeout(requestContext, timeout);
      if (taskNeedTimeout) {
         // configure request context before creating parseq task from the request
        requestContext.putLocalAttr(R2Constants.REQUEST_TIMEOUT, timeout.getValue().intValue());
        requestContext.putLocalAttr(R2Constants.REQUEST_TIMEOUT_IGNORE_IF_HIGHER_THAN_DEFAULT, true);
      }
      Task<Response<T>> requestTask;
      if (RequestGroup.isBatchable(request, config)) {
        requestTask = createBatchableTask(name, request, requestContext, config);
      } else {
        requestTask = Task.async(name, () -> sendRequest(request, requestContext));
      }
      if (!taskNeedTimeout) {
        return requestTask;
      } else {
        // still enforce parseq client timeout if for some reason downstream services are not timed out properly.
        return withTimeout(requestTask, timeout);
      }
    }
docs: We will distinguish two cases in applying timeout to a ParSeq rest.li request task through D2 request timeout.
  Case 1: There is no per request timeout specified in request context of rest.li request, timeout is configured
  through ParSeqRestClient configuration. For this case, we will update request context as:
  REQUEST_TIMEOUT = configured timeout value
  REQUEST_TIMEOUT_IGNORE_IF_HIGHER_THAN_DEFAULT = true
  since in this case, ParSeqRestClient just wants to timeout this request from client side within configured timeout
  without disturbing any lower layer load balancing behaviors.
  
  Case 2: There is per request timeout specified in rest.li request, and there may or may not have timeout specified
  through ParSeqRestClient configuration. For this case, per request timeout specified in rest.li request always
  takes precedence, ParSeq will interpret that users would like to use this to impact lower layer LB behavior, and
  thus will pass down request context unchanged down.