@Override public Disposable schedule(Runnable task, long delay, TimeUnit unit) { return cached.schedule(task, delay, unit); }
private Mono<Void> stopScheduler() { return Mono.fromRunnable(() -> { this.scheduler.dispose(); for (int i = 0; i < 20; i++) { if (this.scheduler.isDisposed()) { break; } try { Thread.sleep(100); } catch (Throwable ex) { break; } } }); }
@Test public void scheduledDoesntReject() { Scheduler s = Schedulers.fromExecutorService(Executors.newSingleThreadScheduledExecutor()); assertThat(s.schedule(() -> {}, 100, TimeUnit.MILLISECONDS)) .describedAs("direct delayed scheduling") .isNotNull(); assertThat(s.schedulePeriodically(() -> {}, 100, 100, TimeUnit.MILLISECONDS)) .describedAs("direct periodic scheduling") .isNotNull(); Worker w = s.createWorker(); assertThat(w.schedule(() -> {}, 100, TimeUnit.MILLISECONDS)) .describedAs("worker delayed scheduling") .isNotNull(); assertThat(w.schedulePeriodically(() -> {}, 100, 100, TimeUnit.MILLISECONDS)) .describedAs("worker periodic scheduling") .isNotNull(); }
@Test(timeout = 10000) public void eviction() throws Exception { Scheduler s = Schedulers.newElastic("test-recycle", 2); ((ElasticScheduler)s).evictor.shutdownNow(); try{ Disposable d = s.schedule(() -> { try { Thread.sleep(10000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); d.dispose(); while(((ElasticScheduler)s).cache.peek() != null){ ((ElasticScheduler)s).eviction(); Thread.sleep(100); } } finally { s.dispose(); s.dispose();//noop } assertThat(((ElasticScheduler)s).cache).isEmpty(); assertThat(s.isDisposed()).isTrue(); }
assertThat(s.isDisposed()).isFalse(); .isThrownBy(() -> s.schedule(() -> { }, 10, TimeUnit.MILLISECONDS)) .as("Scheduler marked as not supporting time scheduling") .isSameAs(Exceptions.failWithRejectedNotTimeCapable()); Disposable d = s.schedulePeriodically(() -> { try { latch.countDown(); s.dispose(); assertThat(s.isDisposed()).isTrue(); .isThrownBy(() -> s.schedule(() -> { })); s.dispose();
@Test public void recursiveParallelCall() throws Exception { Scheduler s = Schedulers.newParallel("work", 4); try { Scheduler.Worker w = s.createWorker(); CountDownLatch latch = new CountDownLatch(2); w.schedule(() -> recursiveCall(w, latch, 0)); latch.await(); } finally { s.dispose(); } }
@Override public Worker createWorker() { return cached.createWorker(); }
@Override public boolean isExpired() { long done = this.done; return done != NOT_DONE && scheduler.now(TimeUnit.MILLISECONDS) - maxAge > done; }
@Override public boolean isDisposed() { return cached.isDisposed(); }
@Override public Disposable schedulePeriodically(Runnable task, long initialDelay, long period, TimeUnit unit) { return cached.schedulePeriodically(task, initialDelay, period, unit); }
@Override public void start() { cached.start(); }
@Test public void scheduledDoesntReject() { Scheduler s = scheduler(); assertThat(s.schedule(() -> {}, 100, TimeUnit.MILLISECONDS)) .describedAs("direct delayed scheduling") .isNotNull(); assertThat(s.schedulePeriodically(() -> {}, 100, 100, TimeUnit.MILLISECONDS)) .describedAs("direct periodic scheduling") .isNotNull(); Scheduler.Worker w = s.createWorker(); assertThat(w.schedule(() -> {}, 100, TimeUnit.MILLISECONDS)) .describedAs("worker delayed scheduling") .isNotNull(); assertThat(w.schedulePeriodically(() -> {}, 100, 100, TimeUnit.MILLISECONDS)) .describedAs("worker periodic scheduling") .isNotNull(); }
assertThat(s.isDisposed()).isFalse(); .isThrownBy(() -> s.schedule(() -> { }, 10, TimeUnit.MILLISECONDS)) .as("Scheduler marked as not supporting time scheduling") .isSameAs(Exceptions.failWithRejectedNotTimeCapable()); Disposable d = s.schedule(() -> { try { latch.countDown(); s.dispose(); assertThat(s.isDisposed()).isTrue(); .isThrownBy(() -> s.schedule(() -> { })); s.dispose();
@Test public void scanCapacity() { Scheduler scheduler = Schedulers.newElastic(2, Thread::new); Scheduler.Worker worker = scheduler.createWorker(); try { assertThat(Scannable.from(scheduler).scan(Scannable.Attr.CAPACITY)).as("scheduler unbounded").isEqualTo(Integer.MAX_VALUE); assertThat(Scannable.from(worker).scan(Scannable.Attr.CAPACITY)).as("worker capacity").isEqualTo(1); } finally { worker.dispose(); scheduler.dispose(); } } }
SingleWorkerScheduler(Scheduler actual) { this.main = actual.createWorker(); }
@Override public long now(TimeUnit unit) { return cached.now(unit); }
@Override public boolean isDisposed() { return actual.isDisposed(); }
@Override public Disposable schedulePeriodically(Runnable task, long initialDelay, long period, TimeUnit unit) { if (tasksRemaining.decrementAndGet() < 0) { throw new RejectedExecutionException("BoundedScheduler schedule periodically: no more tasks"); } return actual.schedulePeriodically(task, initialDelay, period, unit); }