@Test
public void testRateLimit2() throws Exception {

  LogAssert expect = TestLoggers.sys().expect(LimitingExecutorTest.class.getName(), Level.DEBUG, 10,
          LogMatchers.hasFormat("executed nr {}"));
  try (RateLimiter limiter = new RateLimiter(10, Duration.ofSeconds(1), 10)) {
    long replenishInterval = limiter.getPermitReplenishIntervalNanos();
     LOG.debug("replenish interval = {} ", replenishInterval);
    LimitingExecutor.RejectedExecutionHandler rejectedExecutionHandler
            = new LimitingExecutor.RejectedExecutionHandler() {
      @Override
      @SuppressFBWarnings("MDM_THREAD_YIELD")
      public Object reject(final LimitingExecutor executor, final Callable callable)
              throws Exception {
        long nanoTime = TimeSource.nanoTime();
        long lastReplenishmentNanos = limiter.getLastReplenishmentNanos();
        long waitNs = replenishInterval - (nanoTime - lastReplenishmentNanos);
        if (waitNs >= 0) {
          TimeUnit.NANOSECONDS.sleep(waitNs);
        } else {
          LOG.debug("negative wait time {}, current = {}, lastUpdated = {}, permits = {} ", waitNs,
                  nanoTime, lastReplenishmentNanos, limiter.getNrPermits());
        }
        return executor.execute(callable);
      }
    };
    LimitingExecutor<?, Callable<?>> executor
            = new LimitingExecutor<>(rejectedExecutionHandler, limiter.toSemaphore());
    for (int i = 0; i < 10; i++) {
      final int val = i;
      executor.execute(() -> {
        LOG.debug("executed nr {}", val);
        return null;
      });
    }
  }
  expect.assertObservation();
}