@Override public Worker createWorker() { return cached.createWorker(); }
SingleWorkerScheduler(Scheduler actual) { this.main = actual.createWorker(); }
WindowTimeoutSubscriber(CoreSubscriber<? super Flux<T>> actual, int maxSize, long timespan, Scheduler scheduler) { this.actual = actual; this.queue = Queues.unboundedMultiproducer().get(); this.timespan = timespan; this.scheduler = scheduler; this.maxSize = maxSize; this.worker = scheduler.createWorker(); }
BackpressureBufferTimeoutSubscriber(CoreSubscriber<? super T> actual, Duration ttl, Scheduler ttlScheduler, int bufferSize, Consumer<? super T> onBufferEviction) { this.actual = actual; this.ctx = actual.currentContext(); this.onBufferEviction = Objects.requireNonNull(onBufferEviction, "buffer eviction callback must not be null"); this.bufferSizeDouble = bufferSize << 1; this.ttl = ttl; this.ttlScheduler = Objects.requireNonNull(ttlScheduler, "ttl Scheduler must not be null"); this.worker = ttlScheduler.createWorker(); }
@Override public void subscribe(CoreSubscriber<? super T> actual) { Scheduler.Worker w = scheduler.createWorker(); source.subscribe(new DelaySubscriber<T>(actual, delay, w)); }
@Override public void subscribe(CoreSubscriber<? super C> actual) { source.subscribe(new BufferTimeoutSubscriber<>(Operators.serialize(actual), batchSize, timespan, timer.createWorker(), bufferSupplier)); }
@Override public Worker createWorker() { return new BoundedWorker(actual.createWorker()); }
@Test public void scanWorker() { Worker worker = Schedulers.immediate().createWorker(); Scannable s = (Scannable) worker; assertThat(s.scan(Scannable.Attr.TERMINATED)).isFalse(); assertThat(s.scan(Scannable.Attr.CANCELLED)).isFalse(); assertThat(s.scan(Scannable.Attr.NAME)).isEqualTo(Schedulers.IMMEDIATE + ".worker"); worker.dispose(); assertThat(s.scan(Scannable.Attr.TERMINATED)).isTrue(); assertThat(s.scan(Scannable.Attr.CANCELLED)).isTrue(); } }
@Test public void scanSubscriberCancelled() { CoreSubscriber<List<String>> actual = new LambdaSubscriber<>(null, e -> {}, null, null); FluxBufferTimeout.BufferTimeoutSubscriber<String, List<String>> test = new FluxBufferTimeout.BufferTimeoutSubscriber<String, List<String>>( actual, 123, 1000, Schedulers.elastic().createWorker(), ArrayList::new); assertThat(test.scan(Scannable.Attr.CANCELLED)).isFalse(); assertThat(test.scan(Scannable.Attr.TERMINATED)).isFalse(); test.cancel(); assertThat(test.scan(Scannable.Attr.CANCELLED)).isTrue(); assertThat(test.scan(Scannable.Attr.TERMINATED)).isFalse(); }
@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())); } } }
@Test public void shouldShowActualSubscriberDemand() { Subscription[] subscriptionsHolder = new Subscription[1]; CoreSubscriber<List<String>> actual = new LambdaSubscriber<>(null, e -> {}, null, s -> subscriptionsHolder[0] = s); FluxBufferTimeout.BufferTimeoutSubscriber<String, List<String>> test = new FluxBufferTimeout.BufferTimeoutSubscriber<String, List<String>>( actual, 123, 1000, Schedulers.elastic().createWorker(), ArrayList::new); Subscription subscription = Operators.emptySubscription(); test.onSubscribe(subscription); subscriptionsHolder[0].request(10); assertThat(test.scan(Scannable.Attr.REQUESTED_FROM_DOWNSTREAM)).isEqualTo(10L); subscriptionsHolder[0].request(5); assertThat(test.scan(Scannable.Attr.REQUESTED_FROM_DOWNSTREAM)).isEqualTo(15L); }
@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(); } }
@Test public void singleSchedulerPipelining() throws Exception { Scheduler serviceRB = Schedulers.newSingle("rb", true); Scheduler.Worker dispatcher = serviceRB.createWorker(); try { Thread t1 = Thread.currentThread(); Thread[] t2 = { null }; CountDownLatch cdl = new CountDownLatch(1); dispatcher.schedule(() -> { t2[0] = Thread.currentThread(); cdl.countDown(); }); if (!cdl.await(5, TimeUnit.SECONDS)) { Assert.fail("single timed out"); } Assert.assertNotSame(t1, t2[0]); } finally { dispatcher.dispose(); } }
@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 public void downstreamDemandShouldBeAbleToDecreaseOnFullBuffer() { Subscription[] subscriptionsHolder = new Subscription[1]; CoreSubscriber<List<String>> actual = new LambdaSubscriber<>(null, e -> {}, null, s -> subscriptionsHolder[0] = s); FluxBufferTimeout.BufferTimeoutSubscriber<String, List<String>> test = new FluxBufferTimeout.BufferTimeoutSubscriber<String, List<String>>( actual, 5, 1000, Schedulers.elastic().createWorker(), ArrayList::new); Subscription subscription = Operators.emptySubscription(); test.onSubscribe(subscription); subscriptionsHolder[0].request(1); assertThat(test.scan(Scannable.Attr.REQUESTED_FROM_DOWNSTREAM)).isEqualTo(1L); for (int i = 0; i < 5; i++) { test.onNext(String.valueOf(i)); } assertThat(test.scan(Scannable.Attr.REQUESTED_FROM_DOWNSTREAM)).isEqualTo(0L); }
@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(); }
@Override public void subscribe(CoreSubscriber<? super T> actual) { Scheduler.Worker worker = scheduler.createWorker(); SubscribeOnSubscriber<T> parent = new SubscribeOnSubscriber<>(source, actual, worker); actual.onSubscribe(parent); try { worker.schedule(parent); } catch (RejectedExecutionException ree) { if (parent.s != Operators.cancelledSubscription()) { actual.onError(Operators.onRejectedExecution(ree, parent, null, null, actual.currentContext())); } } }
@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(); } } }
@Test public void scanMainSubscriber() { CoreSubscriber<Integer> actual = new LambdaSubscriber<>(null, e -> {}, null, null); FluxSubscribeOn.SubscribeOnSubscriber<Integer> test = new FluxSubscribeOn.SubscribeOnSubscriber<>(Flux.just(1), actual, Schedulers.single().createWorker(), true); Subscription parent = Operators.emptySubscription(); test.onSubscribe(parent); assertThat(test.scan(Scannable.Attr.PARENT)).isSameAs(parent); assertThat(test.scan(Scannable.Attr.ACTUAL)).isSameAs(actual); test.requested = 35; assertThat(test.scan(Scannable.Attr.REQUESTED_FROM_DOWNSTREAM)).isEqualTo(35L); assertThat(test.scan(Scannable.Attr.CANCELLED)).isFalse(); test.cancel(); assertThat(test.scan(Scannable.Attr.CANCELLED)).isTrue(); }
@Test public void scanIntervalRunnable() { Scheduler.Worker worker = Schedulers.single().createWorker(); try { CoreSubscriber<Long> actual = new LambdaSubscriber<>(null, e -> {}, null, null); FluxInterval.IntervalRunnable test = new FluxInterval.IntervalRunnable(actual, worker); assertThat(test.scan(Scannable.Attr.RUN_ON)).isSameAs(worker); assertThat(test.scan(Scannable.Attr.ACTUAL)).isSameAs(actual); assertThat(test.scan(Scannable.Attr.CANCELLED)).isFalse(); test.cancel(); assertThat(test.scan(Scannable.Attr.CANCELLED)).isTrue(); } finally { worker.dispose(); } }