use of io.servicetalk.concurrent.PublisherSource.Subscriber in project servicetalk by apple.
the class SubscribeThrowsTest method singleSubscriberThrows.
@Test
void singleSubscriberThrows() {
Single<String> s = new Single<String>() {
@Override
protected void handleSubscribe(final SingleSource.Subscriber subscriber) {
throw DELIBERATE_EXCEPTION;
}
};
Exception e = assertThrows(ExecutionException.class, () -> s.toFuture().get());
assertThat(e.getCause(), is(DELIBERATE_EXCEPTION));
}
use of io.servicetalk.concurrent.PublisherSource.Subscriber in project servicetalk by apple.
the class BlockingStreamingToStreamingServiceTest method throwAfterSendMetaData.
@Test
void throwAfterSendMetaData() throws Exception {
CountDownLatch onErrorLatch = new CountDownLatch(1);
AtomicReference<Throwable> throwableRef = new AtomicReference<>();
BlockingStreamingHttpService syncService = (ctx, request, response) -> {
response.sendMetaData();
throw DELIBERATE_EXCEPTION;
};
StreamingHttpService asyncService = toStreamingHttpService(syncService, offloadNone()).adaptor();
StreamingHttpResponse asyncResponse = asyncService.handle(mockCtx, reqRespFactory.get("/"), reqRespFactory).subscribeOn(executorExtension.executor()).toFuture().get();
assertMetaData(OK, asyncResponse);
toSource(asyncResponse.payloadBody()).subscribe(new Subscriber<Buffer>() {
@Override
public void onSubscribe(final Subscription s) {
}
@Override
public void onNext(final Buffer s) {
}
@Override
public void onError(final Throwable t) {
throwableRef.set(t);
onErrorLatch.countDown();
}
@Override
public void onComplete() {
}
});
onErrorLatch.await();
assertThat(throwableRef.get(), is(DELIBERATE_EXCEPTION));
}
use of io.servicetalk.concurrent.PublisherSource.Subscriber in project servicetalk by apple.
the class ConnectablePayloadWriter method close0.
private void close0(@Nullable Throwable cause) {
// Set closed before state, because the Subscriber thread depends upon this ordering in the event it needs to
// terminate the Subscriber.
TerminalNotification terminal = cause == null ? complete() : error(cause);
if (closedUpdater.compareAndSet(this, null, terminal)) {
// We need to terminate requested or else we may block indefinitely on subsequent calls to write in
// waitForRequestNDemand.
requested = REQUESTN_TERMINATED;
for (; ; ) {
final Object currState = state;
if (currState instanceof Subscriber) {
if (stateUpdater.compareAndSet(this, currState, State.TERMINATED)) {
terminal.terminate((Subscriber<?>) currState);
break;
}
} else if (currState == State.TERMINATED || stateUpdater.compareAndSet(this, currState, State.TERMINATING)) {
assert currState != State.WAITING_FOR_CONNECTED;
break;
}
}
} else {
Object currState = stateUpdater.getAndSet(this, State.TERMINATED);
if (currState instanceof Subscriber) {
final TerminalNotification currClosed = closed;
assert currClosed != null;
currClosed.terminate((Subscriber<?>) currState);
}
}
}
use of io.servicetalk.concurrent.PublisherSource.Subscriber in project servicetalk by apple.
the class ConcurrentTerminalSubscriberTest method reentrySynchronousOnNextAllowed.
private void reentrySynchronousOnNextAllowed(boolean onComplete) {
AtomicReference<Subscription> subscriptionRef = new AtomicReference<>();
@SuppressWarnings("unchecked") Subscriber<Integer> mockSubscriber = (Subscriber<Integer>) mock(Subscriber.class);
doAnswer((Answer<Void>) invocation -> {
Subscription s = invocation.getArgument(0);
subscriptionRef.set(s);
s.request(1);
return null;
}).when(mockSubscriber).onSubscribe(any());
doAnswer((Answer<Void>) invocation -> {
subscriptionRef.get().request(1);
return null;
}).when(mockSubscriber).onNext(any());
ConcurrentTerminalSubscriber<Integer> subscriber = new ConcurrentTerminalSubscriber<>(mockSubscriber);
publisher.subscribe(subscriber);
publisher.onSubscribe(new Subscription() {
private int i;
@Override
public void request(final long n) {
if (i < 5) {
publisher.onNext(++i);
} else if (i == 5) {
++i;
if (onComplete) {
publisher.onComplete();
} else {
publisher.onError(DELIBERATE_EXCEPTION);
}
// This should be filtered, because we need to protect against concurrent termination this may
// happen concurrently.
publisher.onNext(i);
}
}
@Override
public void cancel() {
}
});
ArgumentCaptor<Integer> onNextArgs = ArgumentCaptor.forClass(Integer.class);
verify(mockSubscriber, times(5)).onNext(onNextArgs.capture());
assertEquals(asList(1, 2, 3, 4, 5), onNextArgs.getAllValues());
if (onComplete) {
verify(mockSubscriber).onComplete();
} else {
verify(mockSubscriber).onError(same(DELIBERATE_EXCEPTION));
}
}
use of io.servicetalk.concurrent.PublisherSource.Subscriber in project servicetalk by apple.
the class ConcurrentTerminalSubscriberTest method concurrentOnComplete.
private void concurrentOnComplete(boolean firstOnComplete, boolean secondOnComplete) throws Exception {
CyclicBarrier terminalEnterBarrier = new CyclicBarrier(2);
CountDownLatch terminatedLatch = new CountDownLatch(1);
@SuppressWarnings("unchecked") Subscriber<Integer> mockSubscriber = (Subscriber<Integer>) mock(Subscriber.class);
doAnswer((Answer<Void>) invocation -> {
Subscription s = invocation.getArgument(0);
s.request(1);
return null;
}).when(mockSubscriber).onSubscribe(any());
doAnswer((Answer<Void>) invocation -> {
terminalEnterBarrier.await();
terminatedLatch.countDown();
return null;
}).when(mockSubscriber).onComplete();
doAnswer((Answer<Void>) invocation -> {
terminalEnterBarrier.await();
terminatedLatch.countDown();
return null;
}).when(mockSubscriber).onError(any());
ConcurrentTerminalSubscriber<Integer> subscriber = new ConcurrentTerminalSubscriber<>(mockSubscriber);
publisher.subscribe(subscriber);
publisher.onSubscribe(subscription);
EXEC.executor().execute(() -> {
if (firstOnComplete) {
publisher.onComplete();
} else {
publisher.onError(DELIBERATE_EXCEPTION);
}
});
terminalEnterBarrier.await();
if (secondOnComplete) {
publisher.onComplete();
} else {
publisher.onError(DELIBERATE_EXCEPTION);
}
terminatedLatch.await();
if (firstOnComplete && secondOnComplete) {
verify(mockSubscriber).onComplete();
} else if (!firstOnComplete && !secondOnComplete) {
verify(mockSubscriber).onError(same(DELIBERATE_EXCEPTION));
} else {
try {
verify(mockSubscriber).onComplete();
} catch (AssertionError e) {
verify(mockSubscriber).onError(same(DELIBERATE_EXCEPTION));
}
}
}
Aggregations