public Disposable schedulePeriodicallyDirect( Runnable run, long initialDelay, long period, TimeUnit unit) { ArrayCompositeResource<Disposable> acr = new ArrayCompositeResource<>(2, Disposable::dispose); Worker w = createWorker(); acr.lazySet(0, w); Runnable decoratedRun = RxJavaPlugins.onSchedule(run); acr.setResource( 1, w.schedulePeriodically( () -> { try { decoratedRun.run(); } catch (final Throwable e) { // make sure the worker is released if the run crashes acr.dispose(); throw e; } }, initialDelay, period, unit)); return acr; }
@Override public void onError(Throwable t) { if (done) { RxJavaPlugins.onError(t); return; } done = true; try { onError.accept(t); } catch (Throwable e) { t.addSuppressed(e); } actual.onError(t); try { onAfterTerminate.run(); } catch (Throwable e) { RxJavaPlugins.onError(e); } }
public Disposable schedulePeriodically( Runnable run, long initialDelay, long period, TimeUnit unit) { MultipleAssignmentResource<Disposable> first = new MultipleAssignmentResource<>(Disposable::dispose); MultipleAssignmentResource<Disposable> mar = new MultipleAssignmentResource<>(Disposable::dispose, first); Runnable decoratedRun = RxJavaPlugins.onSchedule(run); first.setResource( schedule( new Runnable() { long lastNow = now(unit); long startTime = lastNow + initialDelay; long count; @Override public void run() { decoratedRun.run(); long t = now(unit); long c = ++count; long targetTime = startTime + c * period; long delay; // if the current time is less than last time // avoid scheduling the next run too far in the future if (t < lastNow) { delay = period; // TODO not sure about this correction startTime -= lastNow - c * period; } // if the current time is ahead of the target time, // avoid scheduling a bunch of 0 delayed tasks else if (t > targetTime) { delay = period; // TODO not sure about this correction startTime += t - c * period; } else { delay = targetTime - t; } lastNow = t; mar.setResource(schedule(this, delay, unit)); } }, initialDelay, unit)); return mar; }
/** * Schedules the given runnable with the given delay directly on a worker of this scheduler. * * <p>Override this method to provide an efficient implementation that, for example, doesn't have * extra tracking structures for such one-shot executions. * * @param run * @param delay * @param unit * @return */ public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) { Worker w = createWorker(); Runnable decoratedRun = RxJavaPlugins.onSchedule(run); w.schedule( () -> { try { decoratedRun.run(); } finally { w.dispose(); } }, delay, unit); return w; }
@Override public void onComplete() { if (done) { return; } done = true; try { onComplete.run(); } catch (Throwable e) { onError(e); return; } actual.onComplete(); try { onAfterTerminate.run(); } catch (Throwable e) { RxJavaPlugins.onError(e); } }