use of java.util.concurrent.Flow.Subscription in project helidon by oracle.
the class DeferredProcessor method subscribe.
@Override
public void subscribe(Subscriber<? super T> subscriber) {
Objects.requireNonNull(subscriber, "subscriber is null");
if (once.compareAndSet(false, true)) {
subscriber.onSubscribe(this);
if (downstream.compareAndSet(null, subscriber)) {
Subscription s = upstreamActual.get();
if (s != null && s != SubscriptionHelper.CANCELED && upstreamActual.compareAndSet(s, SubscriptionHelper.CANCELED)) {
SubscriptionHelper.deferredSetOnce(upstreamDeferred, requested, s);
}
} else {
// DONE -> DONE_CANCELED : signal terminal event
for (; ; ) {
Subscriber<? super T> s = downstream.get();
if (s == TerminatedSubscriber.CANCELED || s == TerminatedSubscriber.DONE_CANCELED) {
break;
}
if (downstream.compareAndSet(s, TerminatedSubscriber.DONE_CANCELED)) {
Throwable ex = error;
if (ex != null) {
subscriber.onError(ex);
} else {
subscriber.onComplete();
}
break;
}
}
}
} else {
subscriber.onSubscribe(SubscriptionHelper.EMPTY);
subscriber.onError(new IllegalStateException("Only one Subscriber allowed"));
}
}
use of java.util.concurrent.Flow.Subscription in project helidon by oracle.
the class SingleToFuture method cancel.
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
boolean cancelled = super.cancel(mayInterruptIfRunning);
if (cancelled) {
Subscription s = ref.getAndSet(null);
if (s != null) {
s.cancel();
}
source.cancel();
}
return cancelled;
}
use of java.util.concurrent.Flow.Subscription in project helidon by oracle.
the class SingleToFuture method onSubscribe.
@Override
public void onSubscribe(Subscription next) {
Subscription current = ref.getAndSet(next);
Objects.requireNonNull(next, "Subscription cannot be null");
if (current != null) {
next.cancel();
current.cancel();
} else {
next.request(Long.MAX_VALUE);
}
}
use of java.util.concurrent.Flow.Subscription in project helidon by oracle.
the class BufferedEmittingPublisherTest method sanityPublisherCheck.
@Test
public void sanityPublisherCheck() throws Exception {
BufferedEmittingPublisher<Long> publisher = new BufferedEmittingPublisher<Long>() {
};
CountDownLatch finishedLatch = new CountDownLatch(1);
publisher.subscribe(new Flow.Subscriber<Long>() {
Subscription subscription;
@Override
public void onSubscribe(Subscription subscription) {
this.subscription = subscription;
subscription.request(1);
}
@Override
public void onNext(Long value) {
if (!check.compareAndSet(value - 1, value)) {
throw new IllegalStateException("expected: " + (value - 1) + " but found: " + check.get());
}
if (ThreadLocalRandom.current().nextDouble(0, 1) < OTHER_THREAD_EXECUTION_RATIO) {
ForkJoinPool.commonPool().submit(() -> subscription.request(ThreadLocalRandom.current().nextLong(1, BOUND)));
} else {
subscription.request(ThreadLocalRandom.current().nextLong(1, BOUND));
}
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
}
});
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(() -> {
while (!Thread.currentThread().isInterrupted() && seq.get() < ITERATION_COUNT) {
try {
Thread.sleep(ThreadLocalRandom.current().nextLong(0, 2));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException("Interrupted", e);
}
publisher.emit(seq.incrementAndGet());
}
finishedLatch.countDown();
});
try {
if (!finishedLatch.await(10, TimeUnit.SECONDS)) {
fail("Didn't finish in timely manner");
}
} finally {
executorService.shutdown();
}
}
use of java.util.concurrent.Flow.Subscription in project helidon by oracle.
the class MultiFromByteChannelTest method testCancelled.
@Test
void testCancelled() throws Exception {
PeriodicalChannel pc = createChannelWithNoAvailableData(5, 1);
Multi<ByteBuffer> publisher = IoMulti.multiFromByteChannelBuilder(pc).retrySchema(RetrySchema.constant(100)).build();
AtomicReference<Subscription> subscriptionRef = new AtomicReference<>();
final CountDownLatch onNextCalled = new CountDownLatch(1);
AtomicReference<Throwable> failure = new AtomicReference<>();
AtomicBoolean completeCalled = new AtomicBoolean();
publisher.subscribe(new Subscriber<ByteBuffer>() {
@Override
public void onSubscribe(Subscription subscription) {
subscriptionRef.set(subscription);
subscription.request(1);
}
@Override
public void onNext(ByteBuffer item) {
onNextCalled.countDown();
}
@Override
public void onError(Throwable throwable) {
failure.set(throwable);
}
@Override
public void onComplete() {
completeCalled.set(true);
}
});
onNextCalled.await(5, TimeUnit.SECONDS);
subscriptionRef.get().cancel();
assertThat("Should not complete", completeCalled.get(), is(false));
assertThat("Exception should be null", failure.get(), is(nullValue()));
MultiFromByteChannel multi = (MultiFromByteChannel) publisher;
LazyValue<ScheduledExecutorService> executor = multi.executor();
assertThat("Executor should have been used", executor.isLoaded(), is(true));
assertThat("Executor should have been shut down", executor.get().isShutdown(), is(true));
}
Aggregations