/** * Atomically sets the single subscription and requests the missed amount from it. * * @param s the Subscription to set. * @return false if this arbiter is cancelled or there was a subscription already set */ protected final boolean set(Subscription s) { Objects.requireNonNull(s, "s"); Subscription a = this.s; if (a == Operators.cancelledSubscription()) { s.cancel(); return false; } if (a != null) { s.cancel(); Operators.reportSubscriptionSet(); return false; } if (S.compareAndSet(this, null, s)) { long r = REQUESTED.getAndSet(this, 0L); if (r != 0L) { s.request(r); } return true; } a = this.s; if (a != Operators.cancelledSubscription()) { s.cancel(); return false; } Operators.reportSubscriptionSet(); return false; }
@Test public void forEachX() { Subscription s = LazyFutureStream.of(1, 2, 3).forEachX(2, System.out::println); System.out.println("first batch"); s.request(1); }
@Test public void forEachXWithEvents() { List<Integer> list = new ArrayList<>(); LazyFutureStream<Integer> stream = LazyFutureStream.of( () -> 1, () -> 2, () -> 3, (Supplier<Integer>) () -> { throw new RuntimeException(); }) .map(Supplier::get); Subscription s = stream.forEachXEvents(2, i -> list.add(i), e -> error = e, () -> complete = true); assertThat(list, hasItems(1, 2)); assertThat(list.size(), equalTo(2)); System.out.println("first batch"); s.request(1); assertFalse(complete); assertThat(list, hasItems(1, 2, 3)); assertThat(list.size(), equalTo(3)); assertThat(error, nullValue()); s.request(2); assertThat(error, instanceOf(RuntimeException.class)); assertTrue(complete); }
@Override protected void requestMore(long n) { Subscription subscription = SUBSCRIPTION.get(this); if (subscription != UNSUBSCRIBED) { subscription.request(n); } }
@Override public void onSubscribe(Subscription s) { if (SubscriptionHelper.validateSubscription(this.s, s)) { return; } this.s = s; Subscriber<? super U> actual = this.actual; U b; try { b = bufferSupplier.get(); } catch (Throwable e) { cancelled = true; s.cancel(); EmptySubscription.error(e, actual); return; } if (b == null) { cancelled = true; s.cancel(); EmptySubscription.error(new NullPointerException("The buffer supplied is null"), actual); return; } buffer = b; Publisher<B> boundary; try { boundary = boundarySupplier.get(); } catch (Throwable ex) { cancelled = true; s.cancel(); EmptySubscription.error(ex, actual); return; } if (boundary == null) { cancelled = true; s.cancel(); EmptySubscription.error( new NullPointerException("The boundary publisher supplied is null"), actual); return; } BufferBoundarySubscriber<T, U, B> bs = new BufferBoundarySubscriber<T, U, B>(this); other = bs; actual.onSubscribe(this); if (!cancelled) { s.request(Long.MAX_VALUE); boundary.subscribe(bs); } }
void next() { Disposable o = other; U next; try { next = bufferSupplier.get(); } catch (Throwable e) { cancel(); actual.onError(e); return; } if (next == null) { cancel(); actual.onError(new NullPointerException("The buffer supplied is null")); return; } Publisher<B> boundary; try { boundary = boundarySupplier.get(); } catch (Throwable ex) { cancelled = true; s.cancel(); actual.onError(ex); return; } if (boundary == null) { cancelled = true; s.cancel(); actual.onError(new NullPointerException("The boundary publisher supplied is null")); return; } BufferBoundarySubscriber<T, U, B> bs = new BufferBoundarySubscriber<T, U, B>(this); if (!OTHER.compareAndSet(this, o, bs)) { return; } U b; synchronized (this) { b = buffer; if (b == null) { return; } buffer = next; } boundary.subscribe(bs); fastpathEmitMax(b, false, this); }
@Override public void cancel() { Subscription a = s; if (a != Operators.cancelledSubscription()) { a = S.getAndSet(this, Operators.cancelledSubscription()); if (a != null && a != Operators.cancelledSubscription()) { a.cancel(); } } }
@Test public void forEachXTest() { List<Integer> list = new ArrayList<>(); Subscription s = LazyFutureStream.of(1, 2, 3).forEachX(2, i -> list.add(i)); assertThat(list, hasItems(1, 2)); assertThat(list.size(), equalTo(2)); s.request(1); assertThat(list, hasItems(1, 2, 3)); assertThat(list.size(), equalTo(3)); }
@Override public void onNext(Long n) { BackpressureUtils.getAndAdd(COUNTED, AdaptiveConsumerAction.this, n); Subscription upstreamSubscription = AdaptiveConsumerAction.this.upstreamSubscription; if (upstreamSubscription != null) { upstreamSubscription.request(n); } Subscription s = this.s; if (s != null) { s.request(1l); } }
@Override public void cancel() { super.cancel(); FallbackSubscriber fallbackSubscriber = this.fallbackSubscriber; if (fallbackSubscriber != null) { Subscription subscription = fallbackSubscriber.subscription; if (subscription != null) { fallbackSubscriber.subscription = null; subscription.cancel(); } } }
@Override protected void requestUpstream(long capacity, boolean terminated, long elements) { FallbackSubscriber fallbackSubscriber = this.fallbackSubscriber; if (fallbackSubscriber == null) { BackpressureUtils.getAndAdd(REQUESTED, this, elements); super.requestUpstream(capacity, terminated, elements); } else { Subscription subscription = fallbackSubscriber.subscription; if (subscription != null) { subscription.request(elements); } } }
/** Requests the deferred amount if not zero. */ protected final void requestDeferred() { long r = REQUESTED.getAndSet(this, 0L); if (r != 0L) { s.request(r); } }
@Override protected void doOnSubscribe(Subscription subscription) { long p = pendingRequests; if (p > 0) { subscription.request(p); } }
@Override public void onNext(Try<Optional<T>> t) { if (done) { return; } if (t.hasError()) { s.cancel(); onError(t.error()); } else { Optional<T> o = t.value(); if (o.isPresent()) { actual.onNext(o.get()); } else { s.cancel(); onComplete(); } } }
protected final void normalRequest(long n) { Subscription a = s; if (a != null) { a.request(n); } else { Operators.addAndGet(REQUESTED, this, n); a = s; if (a != null) { long r = REQUESTED.getAndSet(this, 0L); if (r != 0L) { a.request(r); } } } }
@Override public void onSubscribe(Subscription s) { super.onSubscribe(s); subscription = s; long r = pendingRequests; if (r > 0) { subscription.request(r); } }
@Override public void onSubscribe(final Subscription s) { if (Operators.validate(subscription, s)) { subscription = s; ctx.channel().closeFuture().addListener(this); s.request(1L); } }
@Override public void onSubscribe(Subscription s) { if (Operators.validate(this.s, s)) { this.s = s; actual.onSubscribe(this); s.request(Long.MAX_VALUE); } }
@Override public void operationComplete(ChannelFuture future) throws Exception { if (log.isDebugEnabled()) { log.debug("Cancel connection"); } if (subscription != null) { subscription.cancel(); } subscription = null; }
/** * Sets the Subscription once but does not request anything. * * @param s the Subscription to set * @return true if successful, false if the current subscription is not null */ protected final boolean setWithoutRequesting(Subscription s) { Objects.requireNonNull(s, "s"); while (true) { Subscription a = this.s; if (a == Operators.cancelledSubscription()) { s.cancel(); return false; } if (a != null) { s.cancel(); Operators.reportSubscriptionSet(); return false; } if (S.compareAndSet(this, null, s)) { return true; } } }
@Override public void cancel() { if (!cancelled) { cancelled = true; s.cancel(); disposeOther(); if (enter()) { queue.clear(); } } }
@Override public void cancel() { if (!cancelled) { cancelled = true; s.cancel(); if (WIP.getAndIncrement(this) == 0) { VALUE.lazySet(this, null); } } }
@Override public void onSubscribe(final Subscription s) { if (BackpressureUtils.checkSubscription(upstreamSubscription, s)) { this.upstreamSubscription = s; try { doOnSubscribe(s); } catch (Throwable t) { Exceptions.throwIfFatal(t); s.cancel(); onError(t); } } }
@Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { promise.tryFailure(future.cause()); if (log.isDebugEnabled()) { log.debug("Write error", future.cause()); } return; } if (subscription != null) { subscription.request(1L); } }
public void demonstrateADetachedGraphStage() throws Exception { // tests: CompletionStage<Integer> result1 = Source.from(Arrays.asList(1, 2, 3)) .via(new TwoBuffer<>()) .runFold(0, (acc, n) -> acc + n, mat); assertEquals(new Integer(6), result1.toCompletableFuture().get(3, TimeUnit.SECONDS)); TestSubscriber.ManualProbe<Integer> subscriber = TestSubscriber.manualProbe(system); TestPublisher.Probe<Integer> publisher = TestPublisher.probe(0, system); RunnableGraph<NotUsed> flow2 = Source.fromPublisher(publisher).via(new TwoBuffer<>()).to(Sink.fromSubscriber(subscriber)); flow2.run(mat); Subscription sub = subscriber.expectSubscription(); // this happens even though the subscriber has not signalled any demand publisher.sendNext(1); publisher.sendNext(2); sub.cancel(); }
@Override public void onNext(T t) { if (done) { return; } try { onNext.accept(t); } catch (Throwable e) { s.cancel(); onError(e); return; } actual.onNext(t); }
@Override public void cancel() { if (subscription != null) { subscription.cancel(); } }
@Override public void request(long n) { if (subscription != null) { subscription.request(n); } }
protected void cancel(Subscription subscription) { if (subscription != SignalType.NOOP_SUBSCRIPTION) { subscription.cancel(); } }
@Override public void onSubscribe(Subscription s) { this.s = s; s.request(1l); }