Search in sources :

Example 6 with BackupRequestsClient

use of com.linkedin.d2.balancer.clients.BackupRequestsClient in project rest.li by linkedin.

the class TestBackupRequestsClient method testRequest.

@Test(dataProvider = "isD2Async")
public void testRequest(boolean isD2Async) throws Exception {
    AtomicReference<ServiceProperties> serviceProperties = new AtomicReference<>();
    serviceProperties.set(createServiceProperties(null));
    BackupRequestsClient client = createClient(serviceProperties::get, isD2Async);
    URI uri = URI.create("d2://testService");
    RestRequest restRequest = new RestRequestBuilder(uri).setEntity(CONTENT).build();
    Future<RestResponse> response = client.restRequest(restRequest);
    assertEquals(response.get().getStatus(), 200);
}
Also used : ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestResponse(com.linkedin.r2.message.rest.RestResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) URI(java.net.URI) Test(org.testng.annotations.Test) AfterTest(org.testng.annotations.AfterTest) BeforeTest(org.testng.annotations.BeforeTest)

Example 7 with BackupRequestsClient

use of com.linkedin.d2.balancer.clients.BackupRequestsClient in project rest.li by linkedin.

the class TestBackupRequestsClient method createClient.

private BackupRequestsClient createClient(Supplier<ServiceProperties> servicePropertiesSupplier, TestBackupRequestsStrategyStatsConsumer statsConsumer, boolean isD2Async) {
    ResponseTimeDistribution hiccupDistribution = new GaussianResponseTimeDistribution(500, 1000, 500, TimeUnit.MILLISECONDS);
    ResponseTimeDistribution responseTime = new GaussianWithHiccupResponseTimeDistribution(2, 10, 5, TimeUnit.MILLISECONDS, hiccupDistribution, 0.02);
    return createClient(servicePropertiesSupplier, statsConsumer, responseTime, isD2Async);
}
Also used : GaussianWithHiccupResponseTimeDistribution(com.linkedin.d2.backuprequests.GaussianWithHiccupResponseTimeDistribution) GaussianWithHiccupResponseTimeDistribution(com.linkedin.d2.backuprequests.GaussianWithHiccupResponseTimeDistribution) ResponseTimeDistribution(com.linkedin.d2.backuprequests.ResponseTimeDistribution) ConstantResponseTimeDistribution(com.linkedin.d2.backuprequests.ConstantResponseTimeDistribution) GaussianResponseTimeDistribution(com.linkedin.d2.backuprequests.GaussianResponseTimeDistribution) GaussianResponseTimeDistribution(com.linkedin.d2.backuprequests.GaussianResponseTimeDistribution)

Example 8 with BackupRequestsClient

use of com.linkedin.d2.balancer.clients.BackupRequestsClient in project rest.li by linkedin.

the class TestBackupRequestsClient method testBackupRequestsRun.

// @Test - Disabled due to flakiness. See SI-3077 to track and resolve this.
public void testBackupRequestsRun() throws Exception {
    final AtomicBoolean shutDown = new AtomicBoolean(false);
    final AtomicLong completed = new AtomicLong(0);
    AtomicReference<ServiceProperties> serviceProperties = new AtomicReference<>();
    TestBackupRequestsStrategyStatsConsumer statsConsumer = new TestBackupRequestsStrategyStatsConsumer();
    serviceProperties.set(createServiceProperties(null));
    final BackupRequestsClient client = createClient(serviceProperties::get, statsConsumer, false);
    final URI uri = URI.create("d2://testService");
    Thread loadGenerator = new Thread(() -> {
        /*
       * Little's theorem: L = a * W
       * W = 10 ms in the test (not including hiccups).
       * We want L to be 100, so a = 100 / 15 = 6.6 events per millisecond
       */
        EventsArrival arrivals = new PoissonEventsArrival(6.6, TimeUnit.MILLISECONDS);
        long lastNano = System.nanoTime();
        while (!shutDown.get()) {
            long nextNano = lastNano + arrivals.nanosToNextEvent();
            try {
                waitUntil(nextNano);
            } catch (Exception e) {
                e.printStackTrace();
            }
            RestRequest restRequest = new RestRequestBuilder(uri).setEntity(CONTENT).build();
            RequestContext requestContext = new RequestContext();
            requestContext.putLocalAttr(R2Constants.OPERATION, "get");
            Set<URI> hosts = new HashSet<>();
            hosts.add(uri);
            requestContext.putLocalAttr("D2-Hint-ExcludedHosts", hosts);
            client.restRequest(restRequest, requestContext, new Callback<RestResponse>() {

                @Override
                public void onSuccess(RestResponse result) {
                    completed.incrementAndGet();
                }

                @Override
                public void onError(Throwable e) {
                }
            });
            lastNano = nextNano;
        }
    });
    loadGenerator.start();
    Thread.sleep(10000);
    serviceProperties.set(createServiceProperties(Arrays.asList(createBackupRequestsConfiguration(5, "get"))));
    long startTime = System.currentTimeMillis();
    while (statsConsumer.getLatencyWithBackup().size() < 1 && System.currentTimeMillis() - startTime < 30000) {
        Thread.sleep(10);
    }
    long endTime = System.currentTimeMillis();
    // this should disable backup requests
    serviceProperties.set(createServiceProperties(Arrays.asList(createBackupRequestsConfiguration(5, "batch_get"))));
    Thread.sleep((endTime - startTime) * 2);
    // initialize shutdown of load generator
    shutDown.set(true);
    // sum up histograms
    Histogram withoutBackup = new Histogram(LatencyMetric.LOWEST_DISCERNIBLE_VALUE, LatencyMetric.HIGHEST_TRACKABLE_VALUE, LatencyMetric.NUMBER_OF_SIGNIFICANT_VALUE_DIGITS);
    Histogram withBackup = new Histogram(LatencyMetric.LOWEST_DISCERNIBLE_VALUE, LatencyMetric.HIGHEST_TRACKABLE_VALUE, LatencyMetric.NUMBER_OF_SIGNIFICANT_VALUE_DIGITS);
    statsConsumer.getLatencyWithoutBackup().stream().forEach(h -> {
        withoutBackup.add(h);
    });
    statsConsumer.getLatencyWithBackup().stream().forEach(h -> {
        withBackup.add(h);
    });
    assertEquals(withoutBackup.getTotalCount(), withBackup.getTotalCount());
    double withoutBackup99 = withoutBackup.getValueAtPercentile(99);
    double withBackup99 = withBackup.getValueAtPercentile(99);
    assertTrue(withBackup99 * 10 < withoutBackup99, "99th percentile is expected to be improved 10x, with backup: " + withBackup99 / 1000000 + "ms, without backup: " + withoutBackup99 / 1000000 + "ms");
}
Also used : AbstractHistogram(org.HdrHistogram.AbstractHistogram) Histogram(org.HdrHistogram.Histogram) URI(java.net.URI) PoissonEventsArrival(com.linkedin.d2.backuprequests.PoissonEventsArrival) EventsArrival(com.linkedin.d2.backuprequests.EventsArrival) RequestContext(com.linkedin.r2.message.RequestContext) PoissonEventsArrival(com.linkedin.d2.backuprequests.PoissonEventsArrival) HashSet(java.util.HashSet) RestResponse(com.linkedin.r2.message.rest.RestResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) JsonParseException(com.fasterxml.jackson.core.JsonParseException) JsonMappingException(com.fasterxml.jackson.databind.JsonMappingException) IOException(java.io.IOException) ServiceUnavailableException(com.linkedin.d2.balancer.ServiceUnavailableException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong) ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) RestRequest(com.linkedin.r2.message.rest.RestRequest) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder)

Example 9 with BackupRequestsClient

use of com.linkedin.d2.balancer.clients.BackupRequestsClient in project rest.li by linkedin.

the class TestBackupRequestsClient method testStatsConsumerUpdateAndRemove.

@Test(dataProvider = "isD2Async")
public void testStatsConsumerUpdateAndRemove(boolean isD2Async) throws Exception {
    AtomicReference<ServiceProperties> serviceProperties = new AtomicReference<>();
    TestBackupRequestsStrategyStatsConsumer statsConsumer = new TestBackupRequestsStrategyStatsConsumer();
    serviceProperties.set(createServiceProperties(null));
    BackupRequestsClient client = createClient(serviceProperties::get, statsConsumer, isD2Async);
    URI uri = URI.create("d2://testService");
    RestRequest restRequest = new RestRequestBuilder(uri).setEntity(CONTENT).build();
    RequestContext requestContext = new RequestContext();
    requestContext.putLocalAttr(R2Constants.OPERATION, "get");
    Future<RestResponse> response = client.restRequest(restRequest, requestContext);
    assertEquals(response.get().getStatus(), 200);
    List<StatsConsumerEvent> events = statsConsumer.getEvents();
    assertEquals(events.size(), 0);
    serviceProperties.set(createServiceProperties(Arrays.asList(createBackupRequestsConfiguration(5, "get"), createBackupRequestsConfiguration(1, "batch_get"))));
    requestContext = new RequestContext();
    requestContext.putLocalAttr(R2Constants.OPERATION, "get");
    response = client.restRequest(restRequest, requestContext);
    assertEquals(response.get().getStatus(), 200);
    events = statsConsumer.getEvents();
    assertEquals(events.size(), 2);
    assertEquals(events.get(0).isEventAdd(), true);
    assertEquals(events.get(0).getService(), SERVICE_NAME);
    assertEquals(events.get(0).getOperation(), "get");
    BackupRequestsStrategyStatsProvider statsProvider1 = events.get(0).getStatsProvider();
    assertNotNull(statsProvider1);
    assertEquals(events.get(1).isEventAdd(), true);
    assertEquals(events.get(1).getService(), SERVICE_NAME);
    assertEquals(events.get(1).getOperation(), "batch_get");
    BackupRequestsStrategyStatsProvider statsProvider2 = events.get(1).getStatsProvider();
    assertNotNull(statsProvider2);
    serviceProperties.set(createServiceProperties(Arrays.asList(createBackupRequestsConfiguration(1, "get"))));
    requestContext = new RequestContext();
    requestContext.putLocalAttr(R2Constants.OPERATION, "get");
    response = client.restRequest(restRequest, requestContext);
    assertEquals(response.get().getStatus(), 200);
    events = statsConsumer.getEvents();
    assertEquals(events.size(), 5);
    assertEquals(events.get(2).isEventAdd(), false);
    assertEquals(events.get(2).getService(), SERVICE_NAME);
    assertEquals(events.get(2).getOperation(), "get");
    BackupRequestsStrategyStatsProvider removedStatsProvider = events.get(2).getStatsProvider();
    assertNotNull(removedStatsProvider);
    assertSame(statsProvider1, removedStatsProvider);
    assertEquals(events.get(3).isEventAdd(), true);
    assertEquals(events.get(3).getService(), SERVICE_NAME);
    assertEquals(events.get(3).getOperation(), "get");
    BackupRequestsStrategyStatsProvider statsProvider3 = events.get(3).getStatsProvider();
    assertNotNull(statsProvider1);
    assertNotSame(statsProvider1, statsProvider3);
    assertEquals(events.get(4).isEventAdd(), false);
    assertEquals(events.get(4).getService(), SERVICE_NAME);
    assertEquals(events.get(4).getOperation(), "batch_get");
    BackupRequestsStrategyStatsProvider removedStatsProvider2 = events.get(4).getStatsProvider();
    assertNotNull(removedStatsProvider);
    assertSame(statsProvider2, removedStatsProvider2);
}
Also used : RestResponse(com.linkedin.r2.message.rest.RestResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) URI(java.net.URI) ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) RestRequest(com.linkedin.r2.message.rest.RestRequest) BackupRequestsStrategyStatsProvider(com.linkedin.d2.backuprequests.BackupRequestsStrategyStatsProvider) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test) AfterTest(org.testng.annotations.AfterTest) BeforeTest(org.testng.annotations.BeforeTest)

Example 10 with BackupRequestsClient

use of com.linkedin.d2.balancer.clients.BackupRequestsClient in project rest.li by linkedin.

the class TestBackupRequestsClient method testStatsConsumerAddRemove.

@Test(dataProvider = "isD2Async")
public void testStatsConsumerAddRemove(boolean isD2Async) throws Exception {
    AtomicReference<ServiceProperties> serviceProperties = new AtomicReference<>();
    TestBackupRequestsStrategyStatsConsumer statsConsumer = new TestBackupRequestsStrategyStatsConsumer();
    serviceProperties.set(createServiceProperties(null));
    BackupRequestsClient client = createClient(serviceProperties::get, statsConsumer, isD2Async);
    URI uri = URI.create("d2://testService");
    RestRequest restRequest = new RestRequestBuilder(uri).setEntity(CONTENT).build();
    RequestContext requestContext = new RequestContext();
    requestContext.putLocalAttr(R2Constants.OPERATION, "get");
    Future<RestResponse> response = client.restRequest(restRequest, requestContext);
    assertEquals(response.get().getStatus(), 200);
    List<StatsConsumerEvent> events = statsConsumer.getEvents();
    assertEquals(events.size(), 0);
    serviceProperties.set(createServiceProperties(Arrays.asList(createBackupRequestsConfiguration(5, "get"))));
    requestContext = new RequestContext();
    requestContext.putLocalAttr(R2Constants.OPERATION, "get");
    response = client.restRequest(restRequest, requestContext);
    assertEquals(response.get().getStatus(), 200);
    events = statsConsumer.getEvents();
    assertEquals(events.size(), 1);
    assertEquals(events.get(0).isEventAdd(), true);
    assertEquals(events.get(0).getService(), SERVICE_NAME);
    assertEquals(events.get(0).getOperation(), "get");
    BackupRequestsStrategyStatsProvider statsProvider = events.get(0).getStatsProvider();
    assertNotNull(statsProvider);
    serviceProperties.set(createServiceProperties(null));
    requestContext = new RequestContext();
    requestContext.putLocalAttr(R2Constants.OPERATION, "get");
    response = client.restRequest(restRequest, requestContext);
    assertEquals(response.get().getStatus(), 200);
    events = statsConsumer.getEvents();
    assertEquals(events.size(), 2);
    assertEquals(events.get(1).isEventAdd(), false);
    assertEquals(events.get(1).getService(), SERVICE_NAME);
    assertEquals(events.get(1).getOperation(), "get");
    BackupRequestsStrategyStatsProvider removedStatsProvider = events.get(1).getStatsProvider();
    assertNotNull(removedStatsProvider);
    assertSame(statsProvider, removedStatsProvider);
}
Also used : RestResponse(com.linkedin.r2.message.rest.RestResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) URI(java.net.URI) ServiceProperties(com.linkedin.d2.balancer.properties.ServiceProperties) RestRequest(com.linkedin.r2.message.rest.RestRequest) BackupRequestsStrategyStatsProvider(com.linkedin.d2.backuprequests.BackupRequestsStrategyStatsProvider) RestRequestBuilder(com.linkedin.r2.message.rest.RestRequestBuilder) RequestContext(com.linkedin.r2.message.RequestContext) Test(org.testng.annotations.Test) AfterTest(org.testng.annotations.AfterTest) BeforeTest(org.testng.annotations.BeforeTest)

Aggregations

RestRequest (com.linkedin.r2.message.rest.RestRequest)8 URI (java.net.URI)8 RequestContext (com.linkedin.r2.message.RequestContext)7 RestRequestBuilder (com.linkedin.r2.message.rest.RestRequestBuilder)7 RestResponse (com.linkedin.r2.message.rest.RestResponse)7 ServiceProperties (com.linkedin.d2.balancer.properties.ServiceProperties)6 AtomicReference (java.util.concurrent.atomic.AtomicReference)6 AfterTest (org.testng.annotations.AfterTest)5 BeforeTest (org.testng.annotations.BeforeTest)5 Test (org.testng.annotations.Test)5 BackupRequestsStrategyStatsProvider (com.linkedin.d2.backuprequests.BackupRequestsStrategyStatsProvider)3 ConstantResponseTimeDistribution (com.linkedin.d2.backuprequests.ConstantResponseTimeDistribution)3 LoadBalancer (com.linkedin.d2.balancer.LoadBalancer)2 ServiceUnavailableException (com.linkedin.d2.balancer.ServiceUnavailableException)2 SimpleLoadBalancer (com.linkedin.d2.balancer.simple.SimpleLoadBalancer)2 JsonParseException (com.fasterxml.jackson.core.JsonParseException)1 JsonMappingException (com.fasterxml.jackson.databind.JsonMappingException)1 BackupRequestsStrategy (com.linkedin.d2.backuprequests.BackupRequestsStrategy)1 EventsArrival (com.linkedin.d2.backuprequests.EventsArrival)1 GaussianResponseTimeDistribution (com.linkedin.d2.backuprequests.GaussianResponseTimeDistribution)1