Search in sources :

Example 1 with AsyncRateLimiter

use of com.linkedin.r2.transport.http.client.AsyncRateLimiter in project rest.li by linkedin.

the class BaseTestSmoothRateLimiter method testSubmitExceedsPermits.

@Test(timeOut = TEST_TIMEOUT)
public void testSubmitExceedsPermits() throws Exception {
    ClockedExecutor clockedExecutor = new ClockedExecutor();
    AsyncRateLimiter rateLimiter = getRateLimiter(clockedExecutor, clockedExecutor, clockedExecutor);
    rateLimiter.setRate(ONE_PERMIT_PER_PERIOD, ONE_MILLISECOND_PERIOD, UNLIMITED_BURST);
    List<FutureCallback<None>> callbacks = new ArrayList<>();
    IntStream.range(0, 5).forEach(i -> {
        FutureCallback<None> callback = new FutureCallback<>();
        rateLimiter.submit(callback);
        callbacks.add(callback);
    });
    Assert.assertEquals(rateLimiter.getPendingTasksCount(), 5);
    // trigger task to run them until current time
    clockedExecutor.runFor(0);
    // We have one permit to begin with so the first task should run immediate and left with 4 pending
    callbacks.get(0).get();
    Assert.assertEquals(rateLimiter.getPendingTasksCount(), 4);
    IntStream.range(0, 1).forEach(i -> assertTrue(callbacks.get(i).isDone()));
    IntStream.range(1, 5).forEach(i -> assertFalse(callbacks.get(i).isDone()));
    // We increment the clock by one period and one more permit should have been issued
    clockedExecutor.runFor(ONE_MILLISECOND_PERIOD);
    callbacks.get(1).get();
    Assert.assertEquals(rateLimiter.getPendingTasksCount(), 3);
    IntStream.range(0, 2).forEach(i -> assertTrue(callbacks.get(i).isDone()));
    IntStream.range(2, 5).forEach(i -> assertFalse(callbacks.get(i).isDone()));
    clockedExecutor.runFor(ONE_MILLISECOND_PERIOD);
    callbacks.get(2).get();
    Assert.assertEquals(rateLimiter.getPendingTasksCount(), 2);
    IntStream.range(0, 3).forEach(i -> assertTrue(callbacks.get(i).isDone()));
    IntStream.range(3, 5).forEach(i -> assertFalse(callbacks.get(i).isDone()));
    clockedExecutor.runFor(ONE_MILLISECOND_PERIOD);
    callbacks.get(3).get();
    Assert.assertEquals(rateLimiter.getPendingTasksCount(), 1);
    IntStream.range(0, 4).forEach(i -> assertTrue(callbacks.get(i).isDone()));
    IntStream.range(4, 5).forEach(i -> assertFalse(callbacks.get(i).isDone()));
    clockedExecutor.runFor(ONE_MILLISECOND_PERIOD);
    callbacks.get(4).get();
    Assert.assertEquals(rateLimiter.getPendingTasksCount(), 0);
    IntStream.range(0, 5).forEach(i -> assertTrue(callbacks.get(i).isDone()));
}
Also used : AsyncRateLimiter(com.linkedin.r2.transport.http.client.AsyncRateLimiter) ArrayList(java.util.ArrayList) ClockedExecutor(com.linkedin.test.util.ClockedExecutor) None(com.linkedin.common.util.None) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 2 with AsyncRateLimiter

use of com.linkedin.r2.transport.http.client.AsyncRateLimiter in project rest.li by linkedin.

the class BaseTestSmoothRateLimiter method testCancelAll.

@Test(timeOut = TEST_TIMEOUT)
public void testCancelAll() throws Exception {
    SettableClock clock = new SettableClock();
    AsyncRateLimiter rateLimiter = getRateLimiter(_scheduledExecutorService, _executor, clock);
    rateLimiter.setRate(ONE_PERMIT_PER_PERIOD, ONE_MILLISECOND_PERIOD, UNLIMITED_BURST);
    List<FutureCallback<None>> callbacks = new ArrayList<>();
    IntStream.range(0, 5).forEach(i -> {
        FutureCallback<None> callback = new FutureCallback<>();
        rateLimiter.submit(callback);
        callbacks.add(callback);
    });
    // We have one permit to begin with so the first task should run immediate and left with four pending
    callbacks.get(0).get();
    IntStream.range(0, 1).forEach(i -> assertTrue(callbacks.get(i).isDone()));
    IntStream.range(1, 5).forEach(i -> assertFalse(callbacks.get(i).isDone()));
    // We cancel all pending callbacks and increment clock by one period. All pending callbacks should be invoked.
    Throwable throwable = new Throwable();
    rateLimiter.cancelAll(throwable);
    clock.addDuration(ONE_MILLISECOND_PERIOD);
    AtomicInteger errorInvocations = new AtomicInteger();
    IntStream.range(1, 5).forEach(i -> {
        try {
            callbacks.get(i).get();
        } catch (Exception e) {
            assertSame(e.getCause(), throwable);
            errorInvocations.incrementAndGet();
        }
    });
    assertEquals(errorInvocations.get(), 4);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AsyncRateLimiter(com.linkedin.r2.transport.http.client.AsyncRateLimiter) ArrayList(java.util.ArrayList) SettableClock(com.linkedin.util.clock.SettableClock) None(com.linkedin.common.util.None) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 3 with AsyncRateLimiter

use of com.linkedin.r2.transport.http.client.AsyncRateLimiter in project rest.li by linkedin.

the class BaseTestSmoothRateLimiter method testConcurrentSubmits.

@Test(timeOut = TEST_TIMEOUT_LONG)
public void testConcurrentSubmits() throws Exception {
    Executor executor = Executors.newFixedThreadPool(CONCURRENT_THREADS);
    AsyncRateLimiter rateLimiter = getRateLimiter(_scheduledExecutorService, this._executor, _clock);
    rateLimiter.setRate(UNLIMITED_PERMITS, ONE_SECOND_PERIOD, UNLIMITED_BURST);
    CountDownLatch countDownLatch = new CountDownLatch(CONCURRENT_SUBMITS);
    LongAdder successCount = new LongAdder();
    LongAdder failureCount = new LongAdder();
    for (int i = 0; i < CONCURRENT_SUBMITS; i++) {
        executor.execute(() -> rateLimiter.submit(new Callback<None>() {

            @Override
            public void onError(Throwable e) {
                failureCount.increment();
                countDownLatch.countDown();
            }

            @Override
            public void onSuccess(None result) {
                successCount.increment();
                countDownLatch.countDown();
            }
        }));
    }
    countDownLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
    Assert.assertEquals(successCount.longValue(), CONCURRENT_SUBMITS);
    Assert.assertEquals(failureCount.longValue(), 0L);
}
Also used : ClockedExecutor(com.linkedin.test.util.ClockedExecutor) Executor(java.util.concurrent.Executor) FutureCallback(com.linkedin.common.callback.FutureCallback) Callback(com.linkedin.common.callback.Callback) LongAdder(java.util.concurrent.atomic.LongAdder) AsyncRateLimiter(com.linkedin.r2.transport.http.client.AsyncRateLimiter) CountDownLatch(java.util.concurrent.CountDownLatch) None(com.linkedin.common.util.None) Test(org.testng.annotations.Test)

Example 4 with AsyncRateLimiter

use of com.linkedin.r2.transport.http.client.AsyncRateLimiter in project rest.li by linkedin.

the class BaseTestSmoothRateLimiter method testMultiSubmitWithinPermits.

@Test(timeOut = TEST_TIMEOUT)
public void testMultiSubmitWithinPermits() throws Exception {
    SettableClock clock = new SettableClock();
    AsyncRateLimiter rateLimiter = getRateLimiter(_scheduledExecutorService, _executor, clock);
    rateLimiter.setRate(128d, ONE_SECOND_PERIOD, UNLIMITED_BURST);
    List<FutureCallback<None>> callbacks = new ArrayList<>();
    for (int i = 0; i < 128; i++) {
        FutureCallback<None> callback = new FutureCallback<>();
        callbacks.add(callback);
        rateLimiter.submit(callback);
    }
    for (int i = 0; i < callbacks.size(); i++) {
        callbacks.get(i).get();
    }
}
Also used : AsyncRateLimiter(com.linkedin.r2.transport.http.client.AsyncRateLimiter) ArrayList(java.util.ArrayList) SettableClock(com.linkedin.util.clock.SettableClock) None(com.linkedin.common.util.None) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Example 5 with AsyncRateLimiter

use of com.linkedin.r2.transport.http.client.AsyncRateLimiter in project rest.li by linkedin.

the class BaseTestSmoothRateLimiter method testSubmitWithinPermits.

@Test(timeOut = TEST_TIMEOUT)
public void testSubmitWithinPermits() throws Exception {
    AsyncRateLimiter rateLimiter = getRateLimiter(_scheduledExecutorService, _executor, _clock);
    rateLimiter.setRate(ONE_PERMIT_PER_PERIOD, ONE_SECOND_PERIOD, UNLIMITED_BURST);
    FutureCallback<None> callback = new FutureCallback<>();
    rateLimiter.submit(callback);
    callback.get();
}
Also used : AsyncRateLimiter(com.linkedin.r2.transport.http.client.AsyncRateLimiter) None(com.linkedin.common.util.None) FutureCallback(com.linkedin.common.callback.FutureCallback) Test(org.testng.annotations.Test)

Aggregations

AsyncRateLimiter (com.linkedin.r2.transport.http.client.AsyncRateLimiter)8 Test (org.testng.annotations.Test)8 FutureCallback (com.linkedin.common.callback.FutureCallback)7 None (com.linkedin.common.util.None)7 ArrayList (java.util.ArrayList)5 ClockedExecutor (com.linkedin.test.util.ClockedExecutor)4 SettableClock (com.linkedin.util.clock.SettableClock)2 Callback (com.linkedin.common.callback.Callback)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 Executor (java.util.concurrent.Executor)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 LongAdder (java.util.concurrent.atomic.LongAdder)1