BufferedRateLimiter implements AsyncRateLimiter { @Override public ListenableFuture<Void> acquireAsync() { totalRequested.incrementAndGet(); if (queue.isEmpty()) { if (permits.incrementAndGet() <= permitsLimit) { if (permits.get() > maxGrantedPermissions.get()) { maxGrantedPermissions.set(permits.get()); } totalGranted.incrementAndGet(); return Futures.immediateFuture(null); } permits.decrementAndGet(); } return putInQueue(); } BufferedRateLimiter(@Value("${cassandra.query.buffer_size}") int queueLimit,
                               @Value("${cassandra.query.concurrent_limit}") int permitsLimit,
                               @Value("${cassandra.query.permit_max_wait_time}") int maxPermitWaitTime); @Override ListenableFuture<Void> acquireAsync(); @Override void release(); @Scheduled(fixedDelayString = "${cassandra.query.rate_limit_print_interval_ms}") void printStats();  }
@Test public void finishedFutureReturnedIfPermitsAreGranted() { BufferedRateLimiter limiter = new BufferedRateLimiter(10, 10, 100); ListenableFuture<Void> actual = limiter.acquireAsync(); assertTrue(actual.isDone()); }
@Test public void notFinishedFutureReturnedIfPermitsAreNotGranted() { BufferedRateLimiter limiter = new BufferedRateLimiter(10, 1, 100); ListenableFuture<Void> actual1 = limiter.acquireAsync(); ListenableFuture<Void> actual2 = limiter.acquireAsync(); assertTrue(actual1.isDone()); assertFalse(actual2.isDone()); }
@Test public void failedFutureReturnedIfQueueIsfull() { BufferedRateLimiter limiter = new BufferedRateLimiter(1, 1, 100); ListenableFuture<Void> actual1 = limiter.acquireAsync(); ListenableFuture<Void> actual2 = limiter.acquireAsync(); ListenableFuture<Void> actual3 = limiter.acquireAsync(); assertTrue(actual1.isDone()); assertFalse(actual2.isDone()); assertTrue(actual3.isDone()); try { actual3.get(); fail(); } catch (Exception e) { assertTrue(e instanceof ExecutionException); Throwable actualCause = e.getCause(); assertTrue(actualCause instanceof BufferLimitException); assertEquals("Rate Limit Buffer is full", actualCause.getMessage()); } }