diff options
Diffstat (limited to 'container-core/src/main/java/com/yahoo/container/handler/threadpool/WorkerCompletionTimingThreadPoolExecutor.java')
-rw-r--r-- | container-core/src/main/java/com/yahoo/container/handler/threadpool/WorkerCompletionTimingThreadPoolExecutor.java | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/container-core/src/main/java/com/yahoo/container/handler/threadpool/WorkerCompletionTimingThreadPoolExecutor.java b/container-core/src/main/java/com/yahoo/container/handler/threadpool/WorkerCompletionTimingThreadPoolExecutor.java new file mode 100644 index 00000000000..9742e7ecfc3 --- /dev/null +++ b/container-core/src/main/java/com/yahoo/container/handler/threadpool/WorkerCompletionTimingThreadPoolExecutor.java @@ -0,0 +1,63 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.container.handler.threadpool; + +import com.yahoo.jdisc.Metric; + +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +/** + * A thread pool executor which maintains the last time a worker completed + * package private for testing + * + * @author Steinar Knutsen + * @author baldersheim + * @author bratseth + */ +class WorkerCompletionTimingThreadPoolExecutor extends ThreadPoolExecutor { + + private static final String UNHANDLED_EXCEPTIONS_METRIC = "jdisc.thread_pool.unhandled_exceptions"; + + volatile long lastThreadAssignmentTimeMillis = System.currentTimeMillis(); + private final AtomicLong startedCount = new AtomicLong(0); + private final AtomicLong completedCount = new AtomicLong(0); + private final Metric metric; + + WorkerCompletionTimingThreadPoolExecutor( + int corePoolSize, + int maximumPoolSize, + long keepAliveTime, + TimeUnit unit, + BlockingQueue<Runnable> workQueue, + ThreadFactory threadFactory, + Metric metric) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); + this.metric = metric; + } + + @Override + protected void beforeExecute(Thread t, Runnable r) { + super.beforeExecute(t, r); + lastThreadAssignmentTimeMillis = System.currentTimeMillis(); + startedCount.incrementAndGet(); + } + + @Override + protected void afterExecute(Runnable r, Throwable t) { + super.afterExecute(r, t); + completedCount.incrementAndGet(); + if (t != null) { + metric.add(UNHANDLED_EXCEPTIONS_METRIC, 1L, metric.createContext(Map.of("exception", t.getClass().getSimpleName()))); + } + } + + @Override + public int getActiveCount() { + return (int)(startedCount.get() - completedCount.get()); + } +} + |