use of io.servicetalk.concurrent.PublisherSource.Subscriber in project servicetalk by apple.
the class PublisherConcatMapIterableTest method upstreamRecoverWithMakesProgress.
@Test
void upstreamRecoverWithMakesProgress() throws Exception {
@SuppressWarnings("unchecked") Subscriber<String> mockSubscriber = mock(Subscriber.class);
CountDownLatch latchOnSubscribe = new CountDownLatch(1);
CountDownLatch latchOnError = new CountDownLatch(1);
AtomicReference<Throwable> causeRef = new AtomicReference<>();
AtomicInteger nextCount = new AtomicInteger();
List<String> results = new ArrayList<>();
doAnswer(a -> {
Subscription s = a.getArgument(0);
s.request(Long.MAX_VALUE);
latchOnSubscribe.countDown();
return null;
}).when(mockSubscriber).onSubscribe(any(Subscription.class));
doAnswer(a -> {
causeRef.set(a.getArgument(0));
latchOnError.countDown();
return null;
}).when(mockSubscriber).onError(eq(DELIBERATE_EXCEPTION));
doAnswer(a -> {
results.add(a.getArgument(0));
if (nextCount.getAndIncrement() == 0) {
throw new DeliberateException();
}
// final exception
throw DELIBERATE_EXCEPTION;
}).when(mockSubscriber).onNext(any());
Processor<List<String>, List<String>> processor = newPublisherProcessor();
toSource(fromSource(processor).onErrorResume(cause -> {
if (cause != DELIBERATE_EXCEPTION) {
// recover!
return from(singletonList("two"));
}
return failed(cause);
}).flatMapConcatIterable(identity())).subscribe(mockSubscriber);
latchOnSubscribe.await();
processor.onNext(asList("one", "ignored!"));
latchOnError.await();
assertThat(results, contains("one", "two"));
assertThat(causeRef.get(), is(DELIBERATE_EXCEPTION));
}
use of io.servicetalk.concurrent.PublisherSource.Subscriber in project servicetalk by apple.
the class PublisherConcatMapIterableTest method cancellableIterableIsCancelled.
@Test
void cancellableIterableIsCancelled() {
toSource(cancellablePublisher.flatMapConcatIterable(identity())).subscribe(subscriber);
cancellablePublisher.onSubscribe(subscription);
subscriber.awaitSubscription().request(1);
AtomicBoolean cancelled = new AtomicBoolean();
cancellablePublisher.onNext(new TestIterableToBlockingIterable<>(asList("one", "two"), (time, unit) -> {
}, (time, unit) -> {
}, () -> cancelled.set(true)));
assertThat(subscriber.takeOnNext(), is("one"));
assertThat(subscriber.pollOnNext(10, MILLISECONDS), is(nullValue()));
assertThat(subscriber.pollTerminal(10, MILLISECONDS), is(nullValue()));
subscriber.awaitSubscription().cancel();
assertTrue(cancelled.get());
}
use of io.servicetalk.concurrent.PublisherSource.Subscriber in project servicetalk by apple.
the class PublisherConcatMapIterableTest method testExceptionFromBufferedOnNextThenTerminalIsPropagated.
@Test
void testExceptionFromBufferedOnNextThenTerminalIsPropagated() {
final DeliberateException ex2 = new DeliberateException();
final AtomicBoolean errored = new AtomicBoolean();
toSource(publisher.flatMapConcatIterable(identity()).map((Function<String, String>) s -> {
if (!errored.getAndSet(true)) {
publisher.onError(DELIBERATE_EXCEPTION);
}
throw ex2;
})).subscribe(subscriber);
subscriber.awaitSubscription().request(3);
publisher.onNext(asList("one", "two", "three"));
assertThat(subscriber.awaitOnError(), is(ex2));
}
use of io.servicetalk.concurrent.PublisherSource.Subscriber in project servicetalk by apple.
the class PublisherFlatMapMergeTest method mappedRecoverMakesProgress.
@Test
void mappedRecoverMakesProgress() throws Exception {
@SuppressWarnings("unchecked") Subscriber<Integer> mockSubscriber = mock(Subscriber.class);
CountDownLatch latchOnSubscribe = new CountDownLatch(1);
CountDownLatch latchOnError = new CountDownLatch(1);
AtomicReference<Throwable> causeRef = new AtomicReference<>();
BlockingQueue<Integer> results = new ArrayBlockingQueue<>(10);
doAnswer(a -> {
Subscription s = a.getArgument(0);
s.request(4);
latchOnSubscribe.countDown();
return null;
}).when(mockSubscriber).onSubscribe(any(Subscription.class));
doAnswer(a -> {
causeRef.set(a.getArgument(0));
latchOnError.countDown();
return null;
}).when(mockSubscriber).onError(any());
doAnswer(a -> {
results.add(a.getArgument(0));
throw DELIBERATE_EXCEPTION;
}).when(mockSubscriber).onNext(any());
Processor<Integer, Integer> processor = newPublisherProcessor();
toSource(fromSource(processor).flatMapMergeDelayError(i -> from(i + 10).onErrorResume(cause -> from(i + 20).concat(failed(cause))))).subscribe(mockSubscriber);
latchOnSubscribe.await();
processor.onNext(1);
assertThat(results.take(), is(11));
assertThat(results.take(), is(21));
assertThat(causeRef.get(), is(nullValue()));
processor.onComplete();
latchOnError.await();
final Throwable t = causeRef.get();
assertThat(t, is(DELIBERATE_EXCEPTION));
}
use of io.servicetalk.concurrent.PublisherSource.Subscriber in project servicetalk by apple.
the class PublisherFlatMapMergeTest method errorFromMappedSubscriberIsSequencedWithOnNextSignals.
@Test
void errorFromMappedSubscriberIsSequencedWithOnNextSignals() throws InterruptedException {
List<TestSubscriptionPublisherPair<Integer>> mappedPublishers = new ArrayList<>();
TestSubscription upstreamSubscription = new TestSubscription();
publisher = new TestPublisher.Builder<Integer>().disableAutoOnSubscribe().build(subscriber1 -> {
subscriber1.onSubscribe(upstreamSubscription);
return subscriber1;
});
toSource(publisher.flatMapMerge(i -> {
TestSubscriptionPublisherPair<Integer> pair = new TestSubscriptionPublisherPair<>(i);
mappedPublishers.add(pair);
return pair.mappedPublisher;
}, 2)).subscribe(subscriber);
Subscription subscription = subscriber.awaitSubscription();
subscription.request(1);
verifyCumulativeDemand(upstreamSubscription, 2);
publisher.onNext(1, 2);
assertThat(mappedPublishers, hasSize(2));
TestSubscriptionPublisherPair<Integer> first = mappedPublishers.get(0);
TestSubscriptionPublisherPair<Integer> second = mappedPublishers.get(1);
first.doOnSubscribe(1);
first.mappedSubscription.awaitRequestN(1);
second.doOnSubscribe(2);
second.mappedSubscription.awaitRequestN(1);
// Exhaust outstanding requestN from downstream
first.mappedPublisher.onNext(10);
assertThat(subscriber.pollAllOnNext(), contains(10));
// These signals should be queued, and the error shouldn't jump the queue.
second.mappedPublisher.onNext(11);
second.mappedPublisher.onError(DELIBERATE_EXCEPTION);
assertThat(subscriber.pollAllOnNext(), is(empty()));
assertTrue(upstreamSubscription.isCancelled());
subscription.request(1);
assertThat(subscriber.pollAllOnNext(), contains(11));
assertThat(subscriber.awaitOnError(), sameInstance(DELIBERATE_EXCEPTION));
}
Aggregations