@Override public void run() { decoratedRun.run(); if (!sd.isDisposed()) { long nextTick; long nowNanoseconds = now(TimeUnit.NANOSECONDS); // If the clock moved in a direction quite a bit, rebase the repetition period if (nowNanoseconds + CLOCK_DRIFT_TOLERANCE_NANOSECONDS < lastNowNanoseconds || nowNanoseconds >= lastNowNanoseconds + periodInNanoseconds + CLOCK_DRIFT_TOLERANCE_NANOSECONDS) { nextTick = nowNanoseconds + periodInNanoseconds; /* * Shift the start point back by the drift as if the whole thing * started count periods ago. */ startInNanoseconds = nextTick - (periodInNanoseconds * (++count)); } else { nextTick = startInNanoseconds + (++count * periodInNanoseconds); } lastNowNanoseconds = nowNanoseconds; long delay = nextTick - nowNanoseconds; sd.replace(schedule(this, delay, TimeUnit.NANOSECONDS)); } }
@Override public void onSubscribe(Subscription s) { if (!SubscriptionHelper.validate(this.upstream, s)) { return; } this.upstream = s; final U b; // NOPMD try { b = ObjectHelper.requireNonNull(bufferSupplier.call(), "The supplied buffer is null"); } catch (Throwable e) { Exceptions.throwIfFatal(e); w.dispose(); s.cancel(); EmptySubscription.error(e, downstream); return; } buffers.add(b); downstream.onSubscribe(this); s.request(Long.MAX_VALUE); w.schedulePeriodically(this, timeskip, timeskip, unit); w.schedule(new RemoveFromBuffer(b), timespan, unit); }
@Test public void workerTracksDisposedState() { Worker worker = scheduler.createWorker(); assertFalse(worker.isDisposed()); worker.dispose(); assertTrue(worker.isDisposed()); }
w.dispose(); assertEquals(Disposables.disposed(), w.schedule(r)); assertEquals(Disposables.disposed(), w.schedule(r, 1, TimeUnit.SECONDS)); assertEquals(Disposables.disposed(), w.schedulePeriodically(r, 1, 1, TimeUnit.SECONDS));
@Test public void disposeSelfPeriodic() { final int[] count = { 0 }; TestScheduler scheduler = new TestScheduler(); Worker worker = scheduler.createWorker(); try { final SequentialDisposable sd = new SequentialDisposable(); Disposable d = worker.schedulePeriodically(new Runnable() { @Override public void run() { count[0]++; sd.dispose(); } }, 100, 100, TimeUnit.MILLISECONDS); sd.set(d); assertEquals(0, count[0]); assertFalse(d.isDisposed()); scheduler.advanceTimeBy(400, TimeUnit.MILLISECONDS); assertEquals(1, count[0]); assertTrue(d.isDisposed()); } finally { worker.dispose(); } }
w.dispose(); assertTrue(w.isDisposed()); assertEquals(Disposables.disposed(), w.schedule(r)); assertEquals(Disposables.disposed(), w.schedule(r, 1, TimeUnit.SECONDS)); assertEquals(Disposables.disposed(), w.schedulePeriodically(r, 1, 1, TimeUnit.SECONDS));
@Override public void onSubscribe(Disposable d) { if (DisposableHelper.validate(this.upstream, d)) { this.upstream = d; Observer<? super Observable<T>> a = downstream; a.onSubscribe(this); if (cancelled) { return; } UnicastSubject<T> w = UnicastSubject.create(bufferSize); window = w; a.onNext(w); Disposable task; ConsumerIndexHolder consumerIndexHolder = new ConsumerIndexHolder(producerIndex, this); if (restartTimerOnMaxSize) { task = worker.schedulePeriodically(consumerIndexHolder, timespan, timespan, unit); } else { task = scheduler.schedulePeriodicallyDirect(consumerIndexHolder, timespan, timespan, unit); } DisposableHelper.replace(timer, task); } }
@Test public void shutdownRejects() { final int[] calls = { 0 }; Runnable r = new Runnable() { @Override public void run() { calls[0]++; } }; Scheduler s = new SingleScheduler(); s.shutdown(); assertEquals(Disposables.disposed(), s.scheduleDirect(r)); assertEquals(Disposables.disposed(), s.scheduleDirect(r, 1, TimeUnit.SECONDS)); assertEquals(Disposables.disposed(), s.schedulePeriodicallyDirect(r, 1, 1, TimeUnit.SECONDS)); Worker w = s.createWorker(); ((ScheduledWorker)w).executor.shutdownNow(); assertEquals(Disposables.disposed(), w.schedule(r)); assertEquals(Disposables.disposed(), w.schedule(r, 1, TimeUnit.SECONDS)); assertEquals(Disposables.disposed(), w.schedulePeriodically(r, 1, 1, TimeUnit.SECONDS)); assertEquals(0, calls[0]); w.dispose(); assertTrue(w.isDisposed()); }
@Override public void onSubscribe(Subscription s) { if (!SubscriptionHelper.validate(this.upstream, s)) { return; } this.upstream = s; U b; try { b = ObjectHelper.requireNonNull(bufferSupplier.call(), "The supplied buffer is null"); } catch (Throwable e) { Exceptions.throwIfFatal(e); w.dispose(); s.cancel(); EmptySubscription.error(e, downstream); return; } buffer = b; downstream.onSubscribe(this); timer = w.schedulePeriodically(this, timespan, timespan, unit); s.request(Long.MAX_VALUE); }
@Test public void shutdownRejects() { final int[] calls = { 0 }; Runnable r = new Runnable() { @Override public void run() { calls[0]++; } }; Scheduler s = getScheduler(); Worker w = s.createWorker(); w.dispose(); assertTrue(w.isDisposed()); assertEquals(Disposables.disposed(), w.schedule(r)); assertEquals(Disposables.disposed(), w.schedule(r, 1, TimeUnit.SECONDS)); assertEquals(Disposables.disposed(), w.schedulePeriodically(r, 1, 1, TimeUnit.SECONDS)); NewThreadWorker actual = (NewThreadWorker)w; CompositeDisposable cd = new CompositeDisposable(); actual.scheduleActual(r, 1, TimeUnit.SECONDS, cd); assertEquals(0, cd.size()); assertEquals(0, calls[0]); }
@Override public void onSubscribe(Disposable d) { if (DisposableHelper.validate(this.upstream, d)) { this.upstream = d; U b; try { b = ObjectHelper.requireNonNull(bufferSupplier.call(), "The buffer supplied is null"); } catch (Throwable e) { Exceptions.throwIfFatal(e); d.dispose(); EmptyDisposable.error(e, downstream); w.dispose(); return; } buffer = b; downstream.onSubscribe(this); timer = w.schedulePeriodically(this, timespan, timespan, unit); } }
@Test public void rejectingExecutorWorker() { ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); exec.shutdown(); List<Throwable> errors = TestHelper.trackPluginErrors(); try { Worker s = Schedulers.from(exec).createWorker(); assertSame(EmptyDisposable.INSTANCE, s.schedule(Functions.EMPTY_RUNNABLE)); s = Schedulers.from(exec).createWorker(); assertSame(EmptyDisposable.INSTANCE, s.schedule(Functions.EMPTY_RUNNABLE, 10, TimeUnit.MILLISECONDS)); s = Schedulers.from(exec).createWorker(); assertSame(EmptyDisposable.INSTANCE, s.schedulePeriodically(Functions.EMPTY_RUNNABLE, 10, 10, TimeUnit.MILLISECONDS)); TestHelper.assertUndeliverable(errors, 0, RejectedExecutionException.class); TestHelper.assertUndeliverable(errors, 1, RejectedExecutionException.class); TestHelper.assertUndeliverable(errors, 2, RejectedExecutionException.class); } finally { RxJavaPlugins.reset(); } }
@Override public void onSubscribe(Disposable d) { if (DisposableHelper.validate(this.upstream, d)) { this.upstream = d; final U b; // NOPMD try { b = ObjectHelper.requireNonNull(bufferSupplier.call(), "The buffer supplied is null"); } catch (Throwable e) { Exceptions.throwIfFatal(e); d.dispose(); EmptyDisposable.error(e, downstream); w.dispose(); return; } buffers.add(b); downstream.onSubscribe(this); w.schedulePeriodically(this, timeskip, timeskip, unit); w.schedule(new RemoveFromBufferEmit(b), timespan, unit); } }
@Test public void rejectingExecutorWorker() { ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); exec.shutdown(); List<Throwable> errors = TestHelper.trackPluginErrors(); try { Worker s = Schedulers.from(exec, true).createWorker(); assertSame(EmptyDisposable.INSTANCE, s.schedule(Functions.EMPTY_RUNNABLE)); s = Schedulers.from(exec, true).createWorker(); assertSame(EmptyDisposable.INSTANCE, s.schedule(Functions.EMPTY_RUNNABLE, 10, TimeUnit.MILLISECONDS)); s = Schedulers.from(exec, true).createWorker(); assertSame(EmptyDisposable.INSTANCE, s.schedulePeriodically(Functions.EMPTY_RUNNABLE, 10, 10, TimeUnit.MILLISECONDS)); TestHelper.assertUndeliverable(errors, 0, RejectedExecutionException.class); TestHelper.assertUndeliverable(errors, 1, RejectedExecutionException.class); TestHelper.assertUndeliverable(errors, 2, RejectedExecutionException.class); } finally { RxJavaPlugins.reset(); } }
@Override public void onSubscribe(Disposable d) { if (DisposableHelper.validate(this.upstream, d)) { this.upstream = d; downstream.onSubscribe(this); if (cancelled) { return; } final UnicastSubject<T> w = UnicastSubject.create(bufferSize); windows.add(w); downstream.onNext(w); worker.schedule(new CompletionTask(w), timespan, unit); worker.schedulePeriodically(this, timeskip, timeskip, unit); } }
@Override public void subscribeActual(Observer<? super Long> observer) { IntervalObserver is = new IntervalObserver(observer); observer.onSubscribe(is); Scheduler sch = scheduler; if (sch instanceof TrampolineScheduler) { Worker worker = sch.createWorker(); is.setResource(worker); worker.schedulePeriodically(is, initialDelay, period, unit); } else { Disposable d = sch.schedulePeriodicallyDirect(is, initialDelay, period, unit); is.setResource(d); } }
@Override public void subscribeActual(Observer<? super Long> observer) { IntervalRangeObserver is = new IntervalRangeObserver(observer, start, end); observer.onSubscribe(is); Scheduler sch = scheduler; if (sch instanceof TrampolineScheduler) { Worker worker = sch.createWorker(); is.setResource(worker); worker.schedulePeriodically(is, initialDelay, period, unit); } else { Disposable d = sch.schedulePeriodicallyDirect(is, initialDelay, period, unit); is.setResource(d); } }
@Override public void subscribeActual(Subscriber<? super Long> s) { IntervalSubscriber is = new IntervalSubscriber(s); s.onSubscribe(is); Scheduler sch = scheduler; if (sch instanceof TrampolineScheduler) { Worker worker = sch.createWorker(); is.setResource(worker); worker.schedulePeriodically(is, initialDelay, period, unit); } else { Disposable d = sch.schedulePeriodicallyDirect(is, initialDelay, period, unit); is.setResource(d); } }
@Override public void subscribeActual(Subscriber<? super Long> s) { IntervalRangeSubscriber is = new IntervalRangeSubscriber(s, start, end); s.onSubscribe(is); Scheduler sch = scheduler; if (sch instanceof TrampolineScheduler) { Worker worker = sch.createWorker(); is.setResource(worker); worker.schedulePeriodically(is, initialDelay, period, unit); } else { Disposable d = sch.schedulePeriodicallyDirect(is, initialDelay, period, unit); is.setResource(d); } }
@Override public boolean isDisposed() { return w.isDisposed(); }