RevAwaiter { void await(long rev, Duration maxWaitTime) throws TimeoutException, InterruptedException { if (currentRev.get() >= rev) { return; } AwaitableRev awaitable = new AwaitableRev(rev); synchronized (pq) { pq.add(awaitable); } synchronized (awaitable) { @Var long now = System.nanoTime(); long deadline = now + maxWaitTime.toNanos(); while (currentRev.get() < rev && now < deadline) { awaitable.wait((deadline - now) / 1000000); now = System.nanoTime(); } if (now >= deadline) { throw new TimeoutException(); } } } RevAwaiter(String nodeName); @Override String toString();  }
@Test public void testAwaitFail() { assertThrows(TimeoutException.class, () -> awaiter.await(1, MS_100)); }