@Test public void asyncFusion() { AssertSubscriber<Object> ts = AssertSubscriber.create(); UnicastProcessor<Integer> up = UnicastProcessor.create(new ConcurrentLinkedQueue<>()); up.map(v -> v + 1) .subscribe(ts); for (int i = 1; i < 11; i++) { up.onNext(i); } up.onComplete(); ts.assertValues(2, 3, 4, 5, 6, 7, 8, 9, 10, 11) .assertNoError() .assertComplete(); }
actual.onError(e); for (UnicastProcessor<T> w : ws) { w.onError(e); w.onComplete(); if (w != null) { if (ws.remove(wo.w)) { wo.w.onComplete(); w = UnicastProcessor.create(processorQueueSupplier.get()); @SuppressWarnings("unchecked") T t = (T) o; w.onNext(t);
@Override public void onNext(T t) { if (done || cancelled) { Operators.onNextDropped(t, currentContext()); return; } if (!queue.offer(t)) { Throwable ex = Operators.onOperatorError(null, Exceptions.failWithOverflow(), t, currentContext()); if(onOverflow != null) { try { onOverflow.accept(t); } catch (Throwable e) { Exceptions.throwIfFatal(e); ex.initCause(e); } } onError(Operators.onOperatorError(null, ex, t, currentContext())); return; } drain(); }
@Override public void onNext(T t) { if (done) { Operators.onNextDropped(t, actual.currentContext()); return; } int i = index; UnicastProcessor<T> w = window; if (cancelled == 0 && i == 0) { WINDOW_COUNT.getAndIncrement(this); w = new UnicastProcessor<>(processorQueueSupplier.get(), this); window = w; actual.onNext(w); } i++; w.onNext(t); if (i == size) { index = 0; window = null; w.onComplete(); } else { index = i; } }
@Test public void switchOnNextDynamicallyOnNext() { UnicastProcessor<Flux<Integer>> up = UnicastProcessor.create(); up.onNext(Flux.range(1, 3)); up.onNext(Flux.range(2, 3).concatWith(Mono.never())); up.onNext(Flux.range(4, 3)); up.onComplete(); StepVerifier.create(Flux.switchOnNext(up)) .expectNext(1, 2, 3, 2, 3, 4, 4, 5, 6) .verifyComplete(); }
@Test public void asyncFusion() { AssertSubscriber<Object> ts = AssertSubscriber.create(); UnicastProcessor<Integer> up = UnicastProcessor.create(new ConcurrentLinkedQueue<>()); up.filter(v -> (v & 1) == 0) .subscribe(ts); for (int i = 1; i < 11; i++) { up.onNext(i); } up.onComplete(); ts.assertValues(2, 4, 6, 8, 10) .assertNoError() .assertComplete(); }
@Test public void asyncFusedThreadBarrier() { UnicastProcessor<Integer> up = UnicastProcessor.create(); up.onNext(1); up.onNext(2); up.onNext(3); up.onNext(4); up.onNext(5); up.onComplete(); StepVerifier.create(up.doFinally(this)) .expectFusion(ASYNC | THREAD_BARRIER, NONE) .expectNext(1, 2, 3, 4, 5) .expectComplete() .verify(); assertEquals(1, calls); assertEquals(SignalType.ON_COMPLETE, signalType); }
/** * Build a {@link FluxProcessor} whose data are emitted by the most recent emitted {@link Publisher}. * The {@link Flux} will complete once both the publishers source and the last switched to {@link Publisher} have * completed. * * <p> * <img class="marble" src="https://raw.githubusercontent.com/reactor/reactor-core/v3.1.3.RELEASE/src/docs/marble/switchonnext.png" alt=""> * * @param <T> the produced type * @return a {@link FluxProcessor} accepting publishers and producing T */ public static <T> FluxProcessor<Publisher<? extends T>, T> switchOnNext() { UnicastProcessor<Publisher<? extends T>> emitter = UnicastProcessor.create(); FluxProcessor<Publisher<? extends T>, T> p = FluxProcessor.wrap(emitter, switchOnNext(emitter)); return p; }
@Test public void subsequentSumAsync() { AssertSubscriber<Integer> ts = AssertSubscriber.create(); UnicastProcessor<Integer> up = UnicastProcessor.create(Queues.<Integer>get(16).get()); up.publish(o -> zip((Object[] a) -> (Integer) a[0] + (Integer) a[1], o, o.skip(1))) .subscribe(ts); up.onNext(1); up.onNext(2); up.onNext(3); up.onNext(4); up.onNext(5); up.onComplete(); ts.assertValues(1 + 2, 2 + 3, 3 + 4, 4 + 5) .assertNoError() .assertComplete(); }
@Test public void backpressuredAsyncFusedCancelled2() { UnicastProcessor<Integer> up = UnicastProcessor.create(); StepVerifier.create(Flux.zip(obj -> (int) obj[0] + (int) obj[1], 1, up, Flux.just(2, 3, 5)), 0) .then(() -> up.onNext(1)) .thenRequest(3) .expectNext(3) .then(() -> up.onNext(2)) .expectNext(5) .thenCancel() .verify(); }
@Test //FIXME use Violation.NO_CLEANUP_ON_TERMINATE public void failNextOnTerminated() { UnicastProcessor<Integer> up = UnicastProcessor.create(); Hooks.onNextDropped(c -> { assertThat(c).isEqualTo(2); }); StepVerifier.create(up.flatMap(Flux::just)) .then(() -> { up.onNext(1); CoreSubscriber<? super Integer> a = up.actual; up.onComplete(); a.onNext(2); }) .expectNext(1) .verifyComplete(); Hooks.resetOnNextDropped(); }
private void handleChannel(int streamId, Payload payload, int initialRequestN) { UnicastProcessor<Payload> frames = UnicastProcessor.create(); channelProcessors.put(streamId, frames); Flux<Payload> payloads = frames .doOnCancel(() -> sendProcessor.onNext(Frame.Cancel.from(streamId))) .doOnError(t -> sendProcessor.onNext(Frame.Error.from(streamId, t))) .doOnRequest(l -> sendProcessor.onNext(Frame.RequestN.from(streamId, l))) .doFinally(signalType -> channelProcessors.remove(streamId)); // not chained, as the payload should be enqueued in the Unicast processor before this method // returns // and any later payload can be processed frames.onNext(payload); handleStream(streamId, requestChannel(payloads), initialRequestN); }
@Test public void bufferSizeBoundedBlockingQueue() { UnicastProcessor processor = UnicastProcessor.create( new LinkedBlockingQueue<>(10)); assertThat(processor.getBufferSize()).isEqualTo(10); }
@Override public <T> Flux<Flux<SenderResult<T>>> sendTransactionally(Publisher<? extends Publisher<? extends SenderRecord<K, V, T>>> transactionRecords) { UnicastProcessor<Object> processor = UnicastProcessor.create(); return Flux.from(transactionRecords) .publishOn(senderOptions.scheduler(), false, 1) .concatMapDelayError(records -> transaction(records, processor), false, 1) .window(processor) .doOnTerminate(() -> processor.onComplete()) .doOnCancel(() -> processor.onComplete()); }
Throwable e = Exceptions.terminate(ERROR, this); if (e != Exceptions.TERMINATED) { w.onError(e); q.clear(); w.onComplete(); w.onNext(v); w.onComplete(); w = new UnicastProcessor<>(pq, this); window = w;
@Test public void failAsyncInnerFusion() { UnicastProcessor<Integer> up = UnicastProcessor.create(); StepVerifier.create(Flux.just(1) .hide() .flatMap(f -> up, 1)) .then(() -> up.onNext(1)) .then(() -> up.onNext(2)) .then(() -> up.onError(new Exception("test"))) .expectNext(1, 2) .verifyErrorMessage("test"); }
Flux.defer( () -> { final UnicastProcessor<Payload> receiver = UnicastProcessor.create(); final int streamId = streamIdSupplier.nextStreamId(); final AtomicBoolean firstRequest = new AtomicBoolean(true); .doOnRequest( n -> { if (firstRequest.compareAndSet(true, false)) { .doOnComplete( () -> { if (contains(streamId) && !receiver.isDisposed()) { sendProcessor.onNext( Frame.PayloadFrame.from( receiver.onComplete(); t -> { errorConsumer.accept(t); receiver.dispose(); }); } else { if (contains(streamId) && !receiver.isDisposed()) { sendProcessor.onNext(Frame.RequestN.from(streamId, n)); .doOnError( t -> { if (contains(streamId) && !receiver.isDisposed()) {
final StepVerifier.Step<O> inputFusedAsyncErrorOutputFusedAsync(OperatorScenario<I, PI, O, PO> scenario) { UnicastProcessor<I> up = UnicastProcessor.create(); up.onNext(item(0)); return StepVerifier.create(scenario.body() .apply(up.as(f -> withFluxSource(new FluxFuseableExceptionOnPoll<>( f, exception()))))) .expectFusion(scenario.fusionMode() & ASYNC); }