private ExecutorServiceWrapper(WorkerCompletionTimingThreadPoolExecutor wrapped, Metric metric, ProcessTerminator processTerminator, long maxThreadExecutionTimeMillis) { this.wrapped = wrapped; this.metric = metric; this.processTerminator = processTerminator; this.maxThreadExecutionTimeMillis = maxThreadExecutionTimeMillis; metric.set(MetricNames.THREAD_POOL_SIZE, wrapped.getPoolSize(), null); metric.set(MetricNames.ACTIVE_THREADS, wrapped.getActiveCount(), null); metric.add(MetricNames.REJECTED_REQUEST, 0, null); metricReporter = new Thread(this::reportMetrics); metricReporter.setDaemon(true); metricReporter.start(); }
public ThreadPoolProvider(ThreadpoolConfig threadpoolConfig, Metric metric, ProcessTerminator processTerminator) { WorkerCompletionTimingThreadPoolExecutor executor = new WorkerCompletionTimingThreadPoolExecutor(threadpoolConfig.maxthreads(), threadpoolConfig.maxthreads(), 0L, TimeUnit.SECONDS, new SynchronousQueue<>(false), ThreadFactoryFactory.getThreadFactory("threadpool")); // Prestart needed, if not all threads will be created by the fist N tasks and hence they might also // get the dreaded thread locals initialized even if they will never run. // That counters what we we want to achieve with the Q that will prefer thread locality. executor.prestartAllCoreThreads(); threadpool = new ExecutorServiceWrapper(executor, metric, processTerminator, threadpoolConfig.maxThreadExecutionTimeSeconds() * 1000L); }
private final void reportMetrics() { try { while (!closed.get()) { metric.set(MetricNames.THREAD_POOL_SIZE, wrapped.getPoolSize(), null); metric.set(MetricNames.ACTIVE_THREADS, wrapped.getActiveCount(), null); Thread.sleep(100); } } catch (InterruptedException e) { } }