From ed37cf20ef1ce2c792d57b02ef6494880b24f72d Mon Sep 17 00:00:00 2001 From: Vladimir Kostyukov Date: Thu, 27 Apr 2017 23:42:18 -0700 Subject: [PATCH] Introduce HashedWheelTimer.pendingTimeouts() Motivation: Fixes #6681. Modification: For the sake of better timer observability, expose the number of pending timeouts through the new HashedWheelTimer.pendingTimeouts method . Result: It's now ridiculously easy to observe Netty timer's very basic and yet important metric, the number of pending tasks/timeouts. --- .../java/io/netty/util/HashedWheelTimer.java | 30 +++++++++---------- .../io/netty/util/HashedWheelTimerTest.java | 17 +++++++++++ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/common/src/main/java/io/netty/util/HashedWheelTimer.java b/common/src/main/java/io/netty/util/HashedWheelTimer.java index 2993142f47..bba59fb584 100644 --- a/common/src/main/java/io/netty/util/HashedWheelTimer.java +++ b/common/src/main/java/io/netty/util/HashedWheelTimer.java @@ -16,7 +16,6 @@ package io.netty.util; import io.netty.util.internal.PlatformDependent; -import io.netty.util.internal.StringUtil; import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLoggerFactory; @@ -405,14 +404,14 @@ public class HashedWheelTimer implements Timer { if (unit == null) { throw new NullPointerException("unit"); } - if (shouldLimitTimeouts()) { - long pendingTimeoutsCount = pendingTimeouts.incrementAndGet(); - if (pendingTimeoutsCount > maxPendingTimeouts) { - pendingTimeouts.decrementAndGet(); - throw new RejectedExecutionException("Number of pending timeouts (" - + pendingTimeoutsCount + ") is greater than or equal to maximum allowed pending " - + "timeouts (" + maxPendingTimeouts + ")"); - } + + long pendingTimeoutsCount = pendingTimeouts.incrementAndGet(); + + if (maxPendingTimeouts > 0 && pendingTimeoutsCount > maxPendingTimeouts) { + pendingTimeouts.decrementAndGet(); + throw new RejectedExecutionException("Number of pending timeouts (" + + pendingTimeoutsCount + ") is greater than or equal to maximum allowed pending " + + "timeouts (" + maxPendingTimeouts + ")"); } start(); @@ -425,8 +424,11 @@ public class HashedWheelTimer implements Timer { return timeout; } - private boolean shouldLimitTimeouts() { - return maxPendingTimeouts > 0; + /** + * Returns the number of pending timeouts of this {@link Timer}. + */ + public long pendingTimeouts() { + return pendingTimeouts.get(); } private static void reportTooManyInstances() { @@ -629,7 +631,7 @@ public class HashedWheelTimer implements Timer { HashedWheelBucket bucket = this.bucket; if (bucket != null) { bucket.remove(this); - } else if (timer.shouldLimitTimeouts()) { + } else { timer.pendingTimeouts.decrementAndGet(); } } @@ -774,9 +776,7 @@ public class HashedWheelTimer implements Timer { timeout.prev = null; timeout.next = null; timeout.bucket = null; - if (timeout.timer.shouldLimitTimeouts()) { - timeout.timer.pendingTimeouts.decrementAndGet(); - } + timeout.timer.pendingTimeouts.decrementAndGet(); return next; } diff --git a/common/src/test/java/io/netty/util/HashedWheelTimerTest.java b/common/src/test/java/io/netty/util/HashedWheelTimerTest.java index 8a55636e8d..e1a7bccc6e 100644 --- a/common/src/test/java/io/netty/util/HashedWheelTimerTest.java +++ b/common/src/test/java/io/netty/util/HashedWheelTimerTest.java @@ -213,6 +213,23 @@ public class HashedWheelTimerTest { timer.stop(); } + @Test() + public void reportPendingTimeouts() throws InterruptedException { + final CountDownLatch latch = new CountDownLatch(1); + final HashedWheelTimer timer = new HashedWheelTimer(); + final Timeout t1 = timer.newTimeout(createNoOpTimerTask(), 100, TimeUnit.MINUTES); + final Timeout t2 = timer.newTimeout(createNoOpTimerTask(), 100, TimeUnit.MINUTES); + timer.newTimeout(createCountDownLatchTimerTask(latch), 90, TimeUnit.MILLISECONDS); + + assertEquals(3, timer.pendingTimeouts()); + t1.cancel(); + t2.cancel(); + latch.await(); + + assertEquals(0, timer.pendingTimeouts()); + timer.stop(); + } + private static TimerTask createNoOpTimerTask() { return new TimerTask() { @Override