@Override public void setWorkFactor(double workFactor) { callbackExecutor.setWorkFactor(workFactor); }
@Override public void setWorkFactor(double workFactor) { callbackExecutor.setWorkFactor(workFactor); }
@Override public void setWorkFactor(double workFactor) { callbackExecutor.setWorkFactor(workFactor); }
@Override public void setWorkFactor(double workFactor) { callbackExecutor.setWorkFactor(workFactor); }
@Override public void setWorkFactor(double workFactor) { callbackExecutor.setWorkFactor(workFactor); }
@Test public void testSetWorkRate() { throttler.setWorkFactor(1.0); assertEquals(1.0, throttler.getWorkFactor()); throttler.setWorkFactor(0.5); assertEquals(0.5, throttler.getWorkFactor()); throttler.setWorkFactor(Throttleable.MIN_WORK_FACTOR); assertEquals(Throttleable.MIN_WORK_FACTOR, throttler.getWorkFactor()); }
@Test public void testDecreaseWorkFactor() { throttler.setWorkFactor(0.5); throttler.setPendingNanos(5000); throttler.setWorkFactor(0.3); assertEquals(5000, throttler.getPendingNanos()); }
@Test public void testNegativePendingNanos() throws InterruptedException { throttler.setWorkFactor(0.5); throttler.setPendingNanos(-1000); assertEquals(-1000, throttler.getPendingNanos()); // Note: we do not expect the delay time to be used because work time + pending delay is // negative. throttler.schedule(NO_OP, 500); // Should not be delayed with negative pending nanos Mockito.verify(scheduledExecutorService, Mockito.never()) .schedule(Mockito.any(Runnable.class), Mockito.anyLong(), Mockito.any(TimeUnit.class)); assertEquals(-1000 + 500, throttler.getPendingNanos()); }
@Test public void testDelayOvershoot() throws InterruptedException { throttler.setWorkFactor(0.5); final long workTimeNanos = TimeUnit.MILLISECONDS.toNanos(5); final long expectedDelayNanos = workTimeNanos; final long actualDelayNanos = TimeUnit.MILLISECONDS.toNanos(6); setActualDelay(actualDelayNanos); throttler.schedule(NO_OP, workTimeNanos); verifyRequestedDelay(expectedDelayNanos); assertEquals(expectedDelayNanos - actualDelayNanos, throttler.getPendingNanos()); }
@Test public void testDelayUndershoot() throws InterruptedException { throttler.setWorkFactor(0.5); final long workTimeNanos = TimeUnit.MILLISECONDS.toNanos(5); final long expectedDelayNanos = workTimeNanos; final long actualDelayNanos = TimeUnit.MILLISECONDS.toNanos(4); setActualDelay(actualDelayNanos); throttler.schedule(NO_OP, workTimeNanos); verifyRequestedDelay(expectedDelayNanos); assertEquals(expectedDelayNanos - actualDelayNanos, throttler.getPendingNanos()); }
@Test public void test50PercentWorkRate() throws InterruptedException { throttler.setWorkFactor(0.5); final long workTimeNanos = TimeUnit.MILLISECONDS.toNanos(5); setActualDelay(workTimeNanos); throttler.schedule(NO_OP, workTimeNanos); // Delay time is same as work time at 50% work rate verifyRequestedDelay(workTimeNanos); assertEquals(0L, throttler.getPendingNanos()); }
@Test public void testClampDelayMillis() throws InterruptedException { final long maxDelayMillis = 10; final long maxDelayNanos = TimeUnit.MILLISECONDS.toNanos(maxDelayMillis); ThrottlingScheduler throttler = new ThrottlingScheduler(maxDelayMillis, scheduledExecutorService, clock); throttler.setWorkFactor(0.5); setActualDelay(maxDelayNanos); // Note work time exceeds maxDelayMillis throttler.schedule(NO_OP, TimeUnit.MILLISECONDS.toNanos(100)); verifyRequestedDelay(maxDelayNanos); assertEquals(0L, throttler.getPendingNanos()); }
@Test public void testMinWorkRate() throws InterruptedException { final double workFactor = Throttleable.MIN_WORK_FACTOR; throttler.setWorkFactor(workFactor); // The math to work out how much to multiply work time to get expected delay time double workToDelayFactor = (1.0 - workFactor) / workFactor; final long workTimeNanos = TimeUnit.MILLISECONDS.toNanos(5); final long delayTimeNanos = (long) (workToDelayFactor * workTimeNanos); setActualDelay(delayTimeNanos); throttler.schedule(NO_OP, workTimeNanos); verifyRequestedDelay(delayTimeNanos); assertEquals(0, throttler.getPendingNanos()); }
@Test public void testOverflowOfDelayNanos() throws InterruptedException { throttler.setWorkFactor(0.5); throttler.setPendingNanos(Long.MAX_VALUE); assertEquals(Long.MAX_VALUE, throttler.getPendingNanos()); // At a 50% work factor we'd expect work and delay to match. The function will try // to increment the pending delay nanos, which could (but should not) result in overflow. long workDurationNs = 5000; setActualDelay(workDurationNs); throttler.schedule(NO_OP, workDurationNs); verifyRequestedDelay(workDurationNs); // Expect delay nanos to be clamped during accumulation, and decreased by expected delay at the end. assertEquals(Long.MAX_VALUE - workDurationNs, throttler.getPendingNanos()); }
@Test public void testNegativePendingNanosGoesPositive() throws InterruptedException { throttler.setWorkFactor(0.5); long startPendingNanos = -1000; throttler.setPendingNanos(startPendingNanos); assertEquals(-1000, throttler.getPendingNanos()); setActualDelay(1250); // We request a delay greater than the starting pending delay. throttler.schedule(NO_OP, 1250); verifyRequestedDelay(1250); // Final pending delay should equal initial pending delay since we delay // for the exact requested amount. assertEquals(startPendingNanos, throttler.getPendingNanos()); }