Parsing the delegate toString would be a usable workaround for the time being for Micrometer, assuming the format is stable across JDK versions. It's better than no alternative, which is where I think we are currently at for the wrapped cases.
On 2021/01/09 1:24, "Doug Lea" <d...@cs.oswego.edu> wrote: On 1/7/21 12:57 PM, Jason Mehrens wrote: > Hi Doug, > > What are your thoughts on promoting monitoring methods from TPE and or FJP to AbstractExecutorService? The default implementations could just return -1. An example precedent is OperatingSystemMXBean::getSystemLoadAverage. The Executors.DelegatedExecutorService could then be modified to extend AbstractExecutorService and forward the new methods and the existing AES::taskFor calls when the wrapped Executor is also an AbstractExecutorService. The return types of the Executors.newXXX would remain the same. Maybe. But for now, here's a cheap trick that might be tolerable: Add to DelegatedExecutorService: public String toString() { return e.toString(); } The juc executors (ThreadPoolExecutor and ForkJoinPool that could be wrapped here) both print pool size, active threads, queued tasks, and completed tasks. It would require not-very-pleasant string parsing in monitoring tools, but this might be good enough for Micrometer and others? > > I suppose the tradeoff is that adding any new default method to ExecutorService and or new methods to AbstractExecutorService could break 3rd party code. > > Jason > > ________________________________________ > From: core-libs-dev <core-libs-dev-r...@openjdk.java.net> on behalf of Doug Lea <d...@cs.oswego.edu> > Sent: Thursday, January 7, 2021 7:09 AM > To: core-libs-dev@openjdk.java.net > Subject: Re: Monitoring wrapped ThreadPoolExecutor returned from Executors > > On 1/5/21 10:11 PM, Tommy Ludwig wrote: >> In the Micrometer project, we provide metrics instrumentation of `ExectorService`s. For `ThreadPoolExecutor`s, we track the number of completed tasks, active tasks, thread pool sizes, task queue size and remaining capacity via methods from `ThreadPoolExecutor`. We are currently using a brittle reflection hack[1] to do this for the wrapped `ThreadPoolExecutor` returned from `Executors` methods `newSingleThreadExecutor` and `newSingleThreadScheduledExecutor`. With the introduction of JEP-396 in JDK 16, our reflection hack throws an InaccessibleObjectException by default. >> >> I am not seeing a proper way to get at the methods we use for the metrics (e.g. `ThreadPoolExecutor::getCompletedTaskCount`) in this case. Is there a way that I am missing? > There's no guarantee that newSingleThreadExecutor returns a restricted > view of a ThreadPoolExecutor, so there can't be a guaranteed way of > accessing it, > > But I'm sympathetic to the idea that under the current implementation > (which is unlikely to change anytime soon), the stats are available, and > should be available to monitoring tools. But none of the ways to do this > are very attractive: Creating a MonitorableExecutorService interface and > returning that? Making the internal view class public with a protected > getExecutor method? > >