@Override public Stream<? extends Scannable> inners() { return Stream.of(executors) .map(exec -> key -> Schedulers.scanExecutor(exec, key)); }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.PARENT) return (executor instanceof Scannable) ? executor : null; if (key == Attr.NAME) return Schedulers.FROM_EXECUTOR + "(" + executor + ",trampolining).worker"; if (key == Attr.BUFFERED || key == Attr.LARGE_BUFFERED) return queue.size(); return Schedulers.scanExecutor(executor, key); } }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.NAME) return Schedulers.FROM_EXECUTOR_SERVICE + "(" + executor + ")"; return Schedulers.scanExecutor(executor, key); }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.NAME) return parent.scanUnsafe(key); if (key == Attr.PARENT) return parent; if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.CAPACITY) { //assume 1 if unknown, otherwise use the one from underlying executor Integer capacity = (Integer) Schedulers.scanExecutor(exec, key); if (capacity == null || capacity == -1) return 1; } return Schedulers.scanExecutor(exec, key); } }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.NAME) return this.toString(); if (key == Attr.CAPACITY || key == Attr.BUFFERED) return 1; //BUFFERED: number of workers doesn't vary return Schedulers.scanExecutor(executor, key); }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.BUFFERED) return tasks.size(); if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.NAME) return "ExecutorServiceWorker"; //could be parallel, single or fromExecutorService return Schedulers.scanExecutor(exec, key); } }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.BUFFERED) return tasks.size(); if (key == Attr.PARENT) return (executor instanceof Scannable) ? executor : null; if (key == Attr.NAME) { //hack to recognize the SingleWorker if (executor instanceof SingleWorkerScheduler) return executor + ".worker"; return Schedulers.FROM_EXECUTOR + "(" + executor + ").worker"; } return Schedulers.scanExecutor(executor, key); } }
@Test public void scanExecutorCapacity() { Executor plain = Runnable::run; ExecutorService plainService = Executors.newSingleThreadExecutor(); ExecutorService threadPool = Executors.newFixedThreadPool(3); ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4); DelegateServiceScheduler.UnsupportedScheduledExecutorService unsupportedScheduledExecutorService = new DelegateServiceScheduler.UnsupportedScheduledExecutorService(threadPool); try { assertThat(Schedulers.scanExecutor(plain, Scannable.Attr.CAPACITY)) .as("plain").isEqualTo(null); assertThat(Schedulers.scanExecutor(plainService, Scannable.Attr.CAPACITY)) .as("plainService").isEqualTo(null); assertThat(Schedulers.scanExecutor(threadPool, Scannable.Attr.CAPACITY)) .as("threadPool").isEqualTo(3); assertThat(Schedulers.scanExecutor(scheduledThreadPool, Scannable.Attr.CAPACITY)) .as("scheduledThreadPool").isEqualTo(Integer.MAX_VALUE); assertThat(Schedulers.scanExecutor(unsupportedScheduledExecutorService, Scannable.Attr.CAPACITY)) .as("unwrapped").isEqualTo(3); } finally { plainService.shutdownNow(); unsupportedScheduledExecutorService.shutdownNow(); threadPool.shutdownNow(); scheduledThreadPool.shutdownNow(); } }
assertThat(Schedulers.scanExecutor(plain, Scannable.Attr.BUFFERED)) .as("plain").isEqualTo(null); assertThat(Schedulers.scanExecutor(plainService, Scannable.Attr.BUFFERED)) .as("plainService").isEqualTo(null); Thread.sleep(50); //give some leeway for the pool to have consistent accounting assertThat(Schedulers.scanExecutor(scheduledThreadPool, Scannable.Attr.BUFFERED)) .as("scheduledThreadPool").isEqualTo(2); }); assertThat(Schedulers.scanExecutor(threadPool, Scannable.Attr.BUFFERED)) .as("threadPool").isEqualTo(1); assertThat(Schedulers.scanExecutor(unsupportedScheduledExecutorService, Scannable.Attr.BUFFERED)) .as("unwrapped").isEqualTo(1); assertThat(Schedulers.scanExecutor(unsupportedScheduledExecutorService, Scannable.Attr.BUFFERED)) .as("unwrapped after task").isEqualTo(0);
@Override public Stream<? extends Scannable> inners() { return Stream.of(executors) .map(exec -> key -> Schedulers.scanExecutor(exec, key)); }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.PARENT) return (executor instanceof Scannable) ? executor : null; if (key == Attr.NAME) return Schedulers.FROM_EXECUTOR + "(" + executor + ",trampolining).worker"; if (key == Attr.BUFFERED || key == Attr.LARGE_BUFFERED) return queue.size(); return Schedulers.scanExecutor(executor, key); } }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.NAME) return Schedulers.FROM_EXECUTOR_SERVICE + "(" + executor + ")"; return Schedulers.scanExecutor(executor, key); }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.NAME) return parent.scanUnsafe(key); if (key == Attr.PARENT) return parent; if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.CAPACITY) { //assume 1 if unknown, otherwise use the one from underlying executor Integer capacity = (Integer) Schedulers.scanExecutor(exec, key); if (capacity == null || capacity == -1) return 1; } return Schedulers.scanExecutor(exec, key); } }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.BUFFERED) return tasks.size(); if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.NAME) return "ExecutorServiceWorker"; //could be parallel, single or fromExecutorService return Schedulers.scanExecutor(exec, key); } }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.NAME) return this.toString(); if (key == Attr.CAPACITY || key == Attr.BUFFERED) return 1; //BUFFERED: number of workers doesn't vary return Schedulers.scanExecutor(executor, key); }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.TERMINATED || key == Attr.CANCELLED) return isDisposed(); if (key == Attr.BUFFERED) return tasks.size(); if (key == Attr.PARENT) return (executor instanceof Scannable) ? executor : null; if (key == Attr.NAME) { //hack to recognize the SingleWorker if (executor instanceof SingleWorkerScheduler) return executor + ".worker"; return Schedulers.FROM_EXECUTOR + "(" + executor + ").worker"; } return Schedulers.scanExecutor(executor, key); } }