Scheduler.Worker w = s.createWorker(); assertThat(w.isDisposed()).isFalse(); CountDownLatch latch = new CountDownLatch(1); CountDownLatch latch2 = shouldCheckDisposeTask() ? new CountDownLatch(1) Disposable d = w.schedule(() -> { try{ latch.countDown(); for(int i = 0; i< n; i++){ try { massCancel[i] = w.schedule(() -> { if(current == Thread.currentThread()){ return; massCancel = null; w.dispose(); w.dispose(); //noop assertThat(w.isDisposed()).isTrue(); .isThrownBy(() -> w.schedule(() -> {})) .isSameAs(Exceptions.failWithRejected());
assertThat(w.isDisposed()).isFalse(); .isThrownBy(() -> w.schedule(() -> { }, 10, TimeUnit.MILLISECONDS)) .as("Worker marked as not supporting time scheduling") .isSameAs(Exceptions.failWithRejectedNotTimeCapable()); Disposable c = w.schedulePeriodically(() -> { try { latch.countDown(); w.dispose(); assertThat(w.isDisposed()).isTrue(); .isThrownBy(() -> w.schedule(() -> { })) .isSameAs(Exceptions.failWithRejected()); w.dispose(); s.dispose();
void requestUpstream(final long n, final Subscription s) { if (!requestOnSeparateThread || Thread.currentThread() == THREAD.get(this)) { s.request(n); } else { try { worker.schedule(() -> s.request(n)); } catch (RejectedExecutionException ree) { if(!worker.isDisposed()) { //FIXME should not throw but if we implement strict // serialization like in StrictSubscriber, onNext will carry an // extra cost throw Operators.onRejectedExecution(ree, this, null, null, actual.currentContext()); } } } }
void trySchedule(long n, Subscription s) { if (Thread.currentThread() == THREAD.get(this)) { s.request(n); } else { try { worker.schedule(() -> s.request(n)); } catch (RejectedExecutionException ree) { if (!worker.isDisposed()) { actual.onError(Operators.onRejectedExecution(ree, this, null, null, actual.currentContext())); } } } }
@Override public void subscribe(CoreSubscriber<? super Long> actual) { Worker w = timedScheduler.createWorker(); IntervalRunnable r = new IntervalRunnable(actual, w); actual.onSubscribe(r); try { w.schedulePeriodically(r, initialDelay, period, unit); } catch (RejectedExecutionException ree) { if (!r.cancelled) { actual.onError(Operators.onRejectedExecution(ree, r, null, null, actual.currentContext())); } } }
@Override public Disposable schedule(Runnable task) { return actual.schedule(decorate(task)); }
@Override public boolean isDisposed() { return actual.isDisposed(); }
@Override public boolean isDisposed() { return delegateWorker.isDisposed(); }
@Override public boolean isDisposed() { return actual.isDisposed(); }
@Override public Disposable schedule(@NonNull Runnable run, long delayTime, TimeUnit unit) { return delegateWorker.schedule(new ExecutionWrappedAction(run), delayTime, unit); }
@Override public Disposable schedule(Runnable task) { return main.schedule(task); }
@Override public Disposable schedulePeriodically(Runnable task, long initialDelay, long period, TimeUnit unit) { return actual.schedulePeriodically(decorate(task), initialDelay, period, unit); } }
@Override public void execute(Runnable command) { main.schedule(command); }
@Override public Disposable schedule(Runnable task, long delay, TimeUnit unit) { return main.schedule(task, delay, unit); }
@Override public Disposable schedulePeriodically(Runnable task, long initialDelay, long period, TimeUnit unit) { return actual.schedulePeriodically(decorate(task), initialDelay, period, unit); } }
@Override public boolean isDisposed() { return main.isDisposed(); }
@Override public void onNext(final T t) { if (done || delayed < 0) { Operators.onNextDropped(t, currentContext()); return; } //keep track of the number of delayed onNext so that //we can also delay onError/onComplete when an onNext //is "in flight" DELAYED.incrementAndGet(this); w.schedule(() -> delayedNext(t), delay, timeUnit); }
@Override public Disposable schedulePeriodically(Runnable task, long initialDelay, long period, TimeUnit unit) { return main.schedulePeriodically(task, initialDelay, period, unit); }
Disposable newPeriod() { try { return worker.schedulePeriodically(new ConsumerIndexHolder(producerIndex, this), timespan, timespan, TimeUnit.MILLISECONDS); } catch (Exception e) { actual.onError(Operators.onRejectedExecution(e, s, null, null, actual.currentContext())); return Disposables.disposed(); } }
@Override public Object scanUnsafe(Attr key) { if (key == Attr.PARENT) return s; if (key == Attr.RUN_ON) return w; if (key == Attr.TERMINATED) return done; if (key == Attr.CANCELLED) return w.isDisposed() && !done; return InnerOperator.super.scanUnsafe(key); }