use of io.servicetalk.concurrent.api.Completable in project servicetalk by apple.
the class ServerGracefulConnectionClosureHandlingTest method setUp.
@BeforeEach
void setUp() throws Exception {
AtomicReference<Runnable> serverClose = new AtomicReference<>();
serverContext = forAddress(localAddress(0)).ioExecutor(SERVER_CTX.ioExecutor()).executor(SERVER_CTX.executor()).executionStrategy(offloadNone()).appendConnectionAcceptorFilter(original -> new DelegatingConnectionAcceptor(original) {
@Override
public Completable accept(final ConnectionContext context) {
((NettyHttpServerConnection) context).onClosing().whenFinally(serverConnectionClosing::countDown).subscribe();
context.onClose().whenFinally(serverConnectionClosed::countDown).subscribe();
return completed();
}
}).listenStreamingAndAwait((ctx, request, responseFactory) -> succeeded(responseFactory.ok().addHeader(CONTENT_LENGTH, valueOf(RESPONSE_CONTENT.length())).payloadBody(request.payloadBody().ignoreElements().concat(from(RESPONSE_CONTENT)), RAW_STRING_SERIALIZER).transformMessageBody(payload -> payload.whenFinally(serverClose.get()))));
serverContext.onClose().whenFinally(serverContextClosed::countDown).subscribe();
serverClose.set(() -> serverContext.closeAsyncGracefully().subscribe());
serverAddress = (InetSocketAddress) serverContext.listenAddress();
}
use of io.servicetalk.concurrent.api.Completable in project servicetalk by apple.
the class NettyPipelinedConnectionTest method writeSubscribeThrowsLetsSubsequentRequestsThrough.
@Test
void writeSubscribeThrowsLetsSubsequentRequestsThrough() {
AtomicBoolean firstReadOperation = new AtomicBoolean();
TestPublisher<Integer> mockReadPublisher1 = new TestPublisher<>();
TestPublisher<Integer> mockReadPublisher2 = new TestPublisher<>();
@SuppressWarnings("unchecked") NettyConnection<Integer, Integer> mockConnection = mock(NettyConnection.class);
doAnswer((Answer<Publisher<Integer>>) invocation -> firstReadOperation.compareAndSet(false, true) ? mockReadPublisher1 : mockReadPublisher2).when(mockConnection).read();
doAnswer((Answer<Completable>) invocation -> new Completable() {
@Override
protected void handleSubscribe(final CompletableSource.Subscriber subscriber) {
throw DELIBERATE_EXCEPTION;
}
}).when(mockConnection).write(eq(writePublisher1), any(), any());
doAnswer((Answer<Completable>) invocation -> {
Publisher<Integer> writePub = invocation.getArgument(0);
return writePub.ignoreElements();
}).when(mockConnection).write(eq(writePublisher2), any(), any());
requester = new NettyPipelinedConnection<>(mockConnection, 2);
toSource(requester.write(writePublisher1)).subscribe(readSubscriber);
toSource(requester.write(writePublisher2)).subscribe(readSubscriber2);
Subscription readSubscription = readSubscriber.awaitSubscription();
readSubscription.request(1);
assertTrue(mockReadPublisher1.isSubscribed());
mockReadPublisher1.onError(newSecondException());
assertThat(readSubscriber.awaitOnError(), is(DELIBERATE_EXCEPTION));
assertFalse(writePublisher1.isSubscribed());
verifySecondRequestProcessed(mockReadPublisher2, mockConnection);
}
use of io.servicetalk.concurrent.api.Completable in project servicetalk by apple.
the class NettyPipelinedConnectionTest method readThrowsClosesConnection.
@Test
void readThrowsClosesConnection() {
@SuppressWarnings("unchecked") NettyConnection<Integer, Integer> mockConnection = mock(NettyConnection.class);
doAnswer((Answer<Publisher<Integer>>) invocation -> {
throw DELIBERATE_EXCEPTION;
}).when(mockConnection).read();
doAnswer((Answer<Completable>) invocation -> {
Publisher<Integer> writePub = invocation.getArgument(0);
return writePub.ignoreElements();
}).when(mockConnection).write(any(), any(), any());
when(mockConnection.closeAsync()).thenReturn(completed());
requester = new NettyPipelinedConnection<>(mockConnection, 2);
toSource(requester.write(writePublisher1)).subscribe(readSubscriber);
Subscription readSubscription = readSubscriber.awaitSubscription();
readSubscription.request(1);
writePublisher1.onError(newSecondException());
assertThat(readSubscriber.awaitOnError(), is(DELIBERATE_EXCEPTION));
assertTrue(writePublisher1.isSubscribed());
verify(mockConnection).closeAsync();
}
use of io.servicetalk.concurrent.api.Completable in project servicetalk by apple.
the class AbstractCompletableOffloadingTest method testOffloading.
protected int testOffloading(BiFunction<Completable, Executor, Completable> offloadingFunction, TerminalOperation terminal) throws InterruptedException {
Runnable appCode = () -> {
try {
// Insert a custom value into AsyncContext map
AsyncContext.put(ASYNC_CONTEXT_CUSTOM_KEY, ASYNC_CONTEXT_VALUE);
capture(CaptureSlot.APP);
// Add thread/context recording test points
final Completable original = testCompletable.liftSync(subscriber -> {
capture(CaptureSlot.OFFLOADED_SUBSCRIBE);
return subscriber;
}).beforeOnSubscribe(cancellable -> capture(CaptureSlot.ORIGINAL_ON_SUBSCRIBE)).beforeFinally(new TerminalSignalConsumer() {
@Override
public void onComplete() {
capture(CaptureSlot.ORIGINAL_ON_COMPLETE);
}
@Override
public void onError(final Throwable throwable) {
capture(CaptureSlot.ORIGINAL_ON_ERROR);
}
@Override
public void cancel() {
capture(CaptureSlot.OFFLOADED_CANCEL);
}
});
// Perform offloading and add more thread/context recording test points
Completable offloaded = offloadingFunction.apply(original, testExecutor.executor()).liftSync(subscriber -> {
capture(CaptureSlot.ORIGINAL_SUBSCRIBE);
return subscriber;
}).beforeOnSubscribe(cancellable -> capture(CaptureSlot.OFFLOADED_ON_SUBSCRIBE)).beforeFinally(new TerminalSignalConsumer() {
@Override
public void onComplete() {
capture(CaptureSlot.OFFLOADED_ON_COMPLETE);
}
@Override
public void onError(final Throwable throwable) {
capture(CaptureSlot.OFFLOADED_ON_ERROR);
}
@Override
public void cancel() {
capture(CaptureSlot.ORIGINAL_CANCEL);
}
});
// subscribe and generate terminal
toSource(offloaded).subscribe(testSubscriber);
assertThat("Unexpected tasks " + testExecutor.executor().queuedTasksPending(), testExecutor.executor().queuedTasksPending(), lessThan(2));
if (1 == testExecutor.executor().queuedTasksPending()) {
// execute offloaded subscribe
testExecutor.executor().executeNextTask();
}
Cancellable cancellable = testSubscriber.awaitSubscription();
assertThat("No Cancellable", cancellable, notNullValue());
testCompletable.awaitSubscribed();
assertThat("Source is not subscribed", testCompletable.isSubscribed());
assertThat("Thread was interrupted", !Thread.currentThread().isInterrupted());
switch(terminal) {
case CANCEL:
cancellable.cancel();
break;
case COMPLETE:
testCompletable.onComplete();
break;
case ERROR:
testCompletable.onError(DELIBERATE_EXCEPTION);
break;
default:
throw new AssertionError("unexpected terminal mode");
}
assertThat("Unexpected tasks " + testExecutor.executor().queuedTasksPending(), testExecutor.executor().queuedTasksPending(), lessThan(2));
if (1 == testExecutor.executor().queuedTasksPending()) {
// execute offloaded terminal
testExecutor.executor().executeNextTask();
}
} catch (Throwable all) {
AbstractOffloadingTest.LOGGER.warn("Unexpected throwable", all);
testSubscriber.onError(all);
}
};
APP_EXECUTOR_EXT.executor().execute(appCode);
// Ensure we reached the correct terminal condition
switch(terminal) {
case CANCEL:
testCancellable.awaitCancelled();
break;
case ERROR:
Throwable thrown = testSubscriber.awaitOnError();
assertThat("unexpected exception " + thrown, thrown, sameInstance(DELIBERATE_EXCEPTION));
break;
case COMPLETE:
testSubscriber.awaitOnComplete();
break;
default:
throw new AssertionError("unexpected terminal mode");
}
// Ensure that Async Context Map was correctly set during signals
ContextMap appMap = capturedContexts.captured(CaptureSlot.APP);
assertThat(appMap, notNullValue());
ContextMap subscribeMap = capturedContexts.captured(CaptureSlot.ORIGINAL_SUBSCRIBE);
assertThat(subscribeMap, notNullValue());
assertThat("Map was shared not copied", subscribeMap, not(sameInstance(appMap)));
assertThat("Missing custom async context entry ", subscribeMap.get(ASYNC_CONTEXT_CUSTOM_KEY), sameInstance(ASYNC_CONTEXT_VALUE));
EnumSet<CaptureSlot> checkSlots = EnumSet.complementOf(EnumSet.of(CaptureSlot.APP, CaptureSlot.ORIGINAL_SUBSCRIBE));
checkSlots.stream().filter(slot -> null != capturedContexts.captured(slot)).forEach(slot -> {
ContextMap map = capturedContexts.captured(slot);
assertThat("Context map was not captured", map, is(notNullValue()));
assertThat("Custom key missing from context map", map.containsKey(ASYNC_CONTEXT_CUSTOM_KEY));
assertThat("Unexpected context map @ slot " + slot + " : " + map, map, sameInstance(subscribeMap));
});
// Ensure that all offloading completed.
assertThat("Offloading pending", testExecutor.executor().queuedTasksPending(), is(0));
return testExecutor.executor().queuedTasksExecuted();
}
use of io.servicetalk.concurrent.api.Completable in project servicetalk by apple.
the class RepeatWhenTest method init.
@SuppressWarnings("unchecked")
private void init(TestPublisher<Integer> source) {
this.source = source;
shouldRepeat = (IntFunction<Completable>) mock(IntFunction.class);
repeatSignal = new LegacyTestCompletable();
when(shouldRepeat.apply(anyInt())).thenAnswer(invocation -> {
repeatSignal = new LegacyTestCompletable();
return repeatSignal;
});
toSource(source.repeatWhen(shouldRepeat)).subscribe(subscriber);
}
Aggregations