@Override
  public Future<RestResponse> restRequest(RestRequest request)
  {
    return restRequest(request, new RequestContext());
  }
@Test(invocationCount = 3, dataProvider = "isD2Async", retryAnalyzer = ThreeRetries.class) // Appears to be flaky in CI
  public void testRequestWithHint(boolean isD2Async) throws Exception
  {
    int responseDelayNano = 100000000; //1s till response comes back
    int backupDelayNano = 50000000; // make backup request after 0.5 second
    Deque<URI> hostsReceivingRequest = new ConcurrentLinkedDeque<>();
    BackupRequestsClient client = createAlwaysBackupClientWithHosts(
            Arrays.asList("http://test1.com:123", "http://test2.com:123"),
            hostsReceivingRequest,
            responseDelayNano,
            backupDelayNano,
            isD2Async
        );

    URI uri = URI.create("d2://testService");
    RestRequest restRequest = new RestRequestBuilder(uri).setEntity(CONTENT).build();
    RequestContext context = new RequestContext();
    context.putLocalAttr(R2Constants.OPERATION, "get");

    // case 1: no hint, backup request should be made normally
    RequestContext context1 = context.clone();
    Future<RestResponse> response1 = client.restRequest(restRequest, context1);
    assertEquals(response1.get().getStatus(), 200);
    assertEquals(hostsReceivingRequest.size(), 2);
    assertEquals(new HashSet<>(hostsReceivingRequest).size(), 2);
    hostsReceivingRequest.clear();

    // case 2: hint specified but won't accept other host, backup request will not be made.
    RequestContext context2 = context.clone();
    URI hint = new URI("http://test1.com:123");
    KeyMapper.TargetHostHints.setRequestContextTargetHost(context2, hint);
    Future<RestResponse> response2 = client.restRequest(restRequest, context2);
    assertEquals(response2.get().getStatus(), 200);
    assertEquals(hostsReceivingRequest.size(), 1);
    assertEquals(hostsReceivingRequest.poll(), hint);
    hostsReceivingRequest.clear();

    // case 3: hint specified and set flag to accept other host, backup request will be made to a different host.
    RequestContext context3 = context.clone();
    KeyMapper.TargetHostHints.setRequestContextTargetHost(context3, hint);
    KeyMapper.TargetHostHints.setRequestContextOtherHostAcceptable(context3, true);
    Future<RestResponse> response3 = client.restRequest(restRequest, context3);
    assertEquals(response3.get().getStatus(), 200);
    assertEquals(hostsReceivingRequest.size(), 2);
    // The first request should be made to the hinted host while the second should go to the other.
    assertEquals(hostsReceivingRequest.toArray(), new URI[]{new URI("http://test1.com:123"), new URI("http://test2.com:123")});
    assertEquals(new HashSet<>(hostsReceivingRequest).size(), 2);
  }