Added misuse detection to MemoryAwareThreadPoolExecutor and HashedWheelTimer, where a user can create too many instances
This commit is contained in:
parent
065218fd10
commit
3d355eb48a
@ -32,6 +32,8 @@ import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.jboss.netty.channel.Channel;
|
||||
@ -87,6 +89,10 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
|
||||
private static final InternalLogger logger =
|
||||
InternalLoggerFactory.getInstance(MemoryAwareThreadPoolExecutor.class);
|
||||
|
||||
private static final int MISUSE_WARNING_THRESHOLD = 1024;
|
||||
private static final AtomicInteger activeInstances = new AtomicInteger();
|
||||
private static final AtomicBoolean loggedMisuseWarning = new AtomicBoolean();
|
||||
|
||||
private volatile Settings settings;
|
||||
|
||||
private final ConcurrentMap<Channel, AtomicLong> channelCounters =
|
||||
@ -194,6 +200,23 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
|
||||
|
||||
settings = new Settings(
|
||||
objectSizeEstimator, maxChannelMemorySize, maxTotalMemorySize);
|
||||
|
||||
// Misuse check
|
||||
int activeInstances = MemoryAwareThreadPoolExecutor.activeInstances.incrementAndGet();
|
||||
if (activeInstances >= MISUSE_WARNING_THRESHOLD &&
|
||||
loggedMisuseWarning.compareAndSet(false, true)) {
|
||||
logger.warn(
|
||||
"There are too many active " + getClass().getSimpleName() +
|
||||
" instances (" + activeInstances + ") - you should share " +
|
||||
"the small number of instances to avoid excessive resource " +
|
||||
"consumption.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void terminated() {
|
||||
super.terminated();
|
||||
activeInstances.decrementAndGet();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,6 +53,10 @@ public class HashedWheelTimer implements Timer {
|
||||
InternalLoggerFactory.getInstance(HashedWheelTimer.class);
|
||||
private static final AtomicInteger id = new AtomicInteger();
|
||||
|
||||
private static final int MISUSE_WARNING_THRESHOLD = 1024;
|
||||
private static final AtomicInteger activeInstances = new AtomicInteger();
|
||||
private static final AtomicBoolean loggedMisuseWarning = new AtomicBoolean();
|
||||
|
||||
private final Worker worker = new Worker();
|
||||
final Thread workerThread;
|
||||
final AtomicBoolean shutdown = new AtomicBoolean();
|
||||
@ -125,6 +129,17 @@ public class HashedWheelTimer implements Timer {
|
||||
|
||||
workerThread = threadFactory.newThread(new ThreadRenamingRunnable(
|
||||
worker, "Hashed wheel timer #" + id.incrementAndGet()));
|
||||
|
||||
// Misuse check
|
||||
int activeInstances = HashedWheelTimer.activeInstances.incrementAndGet();
|
||||
if (activeInstances >= MISUSE_WARNING_THRESHOLD &&
|
||||
loggedMisuseWarning.compareAndSet(false, true)) {
|
||||
logger.warn(
|
||||
"There are too many active " + getClass().getSimpleName() +
|
||||
" instances (" + activeInstances + ") - you should share " +
|
||||
"the small number of instances to avoid excessive resource " +
|
||||
"consumption.");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -188,6 +203,8 @@ public class HashedWheelTimer implements Timer {
|
||||
}
|
||||
}
|
||||
|
||||
activeInstances.decrementAndGet();
|
||||
|
||||
Set<Timeout> unprocessedTimeouts = new HashSet<Timeout>();
|
||||
for (Set<HashedWheelTimeout> bucket: wheel) {
|
||||
unprocessedTimeouts.addAll(bucket);
|
||||
|
Loading…
x
Reference in New Issue
Block a user