subprojects/parseq-restli-client/src/main/java/com/linkedin/restli/client/ParSeqRestClient.java
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);
    }
  }
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);
    }
  }
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 ) ; } }
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.
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 .