use of io.smallrye.mutiny.subscription.Cancellable in project smallrye-reactive-messaging by smallrye.
the class ChannelAutoBroadcastTest method testPayloadBroadcasting.
@Test
public void testPayloadBroadcasting() {
addBeanClass(PayloadConsumer.class, Producer.class);
initialize();
Producer producer = get(Producer.class);
PayloadConsumer consumer = get(PayloadConsumer.class);
List<Integer> messages1 = new ArrayList<>();
Cancellable cancellable = consumer.get().subscribe().with(messages1::add);
producer.emitter().emit(1);
assertThat(messages1).containsExactly(1);
assertThat(producer.acks()).isEqualTo(1);
List<Integer> messages2 = new ArrayList<>();
Cancellable cancellable2 = consumer.get().subscribe().with(messages2::add);
producer.emitter().emit(2);
assertThat(messages1).containsExactly(1, 2);
assertThat(messages2).containsExactly(2);
assertThat(producer.acks()).isEqualTo(2);
producer.emitter().emit(3).emit(4).emit(5);
assertThat(messages1).containsExactly(1, 2, 3, 4, 5);
assertThat(messages2).containsExactly(2, 3, 4, 5);
assertThat(producer.acks()).isEqualTo(5);
cancellable.cancel();
producer.emitter().emit(6).emit(7);
assertThat(messages1).containsExactly(1, 2, 3, 4, 5);
assertThat(messages2).containsExactly(2, 3, 4, 5, 6, 7);
assertThat(producer.acks()).isEqualTo(7);
cancellable2.cancel();
producer.emitter().emit(8);
assertThat(messages1).containsExactly(1, 2, 3, 4, 5);
assertThat(messages2).containsExactly(2, 3, 4, 5, 6, 7);
// Acknowledging even without consumers
assertThat(producer.acks()).isEqualTo(8);
}
use of io.smallrye.mutiny.subscription.Cancellable in project smallrye-graphql by smallrye.
the class GraphQLTransportWSSubprotocolHandler method initialize.
private Uni<Void> initialize() {
return Uni.createFrom().emitter(initializationEmitter -> {
if (log.isTraceEnabled()) {
log.trace("Initializing websocket with graphql-transport-ws protocol");
}
connectionInitMessage = Json.createObjectBuilder().add("type", "connection_init").build();
pongMessage = Json.createObjectBuilder().add("type", "pong").add("payload", Json.createObjectBuilder().add("message", "keepalive")).build();
webSocket.closeHandler((v) -> {
onClose.run();
if (webSocket.closeStatusCode() != null) {
if (webSocket.closeStatusCode() == 1000) {
log.debug("WebSocket closed with status code 1000");
// even if the status code is OK, any unfinished single-result operation
// should be marked as failed
uniOperations.forEach((id, emitter) -> emitter.fail(new InvalidResponseException("Connection closed before data was received")));
multiOperations.forEach((id, emitter) -> emitter.complete());
} else {
InvalidResponseException exception = new InvalidResponseException("Server closed the websocket connection with code: " + webSocket.closeStatusCode() + " and reason: " + webSocket.closeReason());
uniOperations.forEach((id, emitter) -> emitter.fail(exception));
multiOperations.forEach((id, emitter) -> emitter.fail(exception));
}
} else {
InvalidResponseException exception = new InvalidResponseException("Connection closed");
uniOperations.forEach((id, emitter) -> emitter.fail(exception));
multiOperations.forEach((id, emitter) -> emitter.fail(exception));
}
});
webSocket.exceptionHandler(this::failAllActiveOperationsWith);
send(webSocket, connectionInitMessage);
// set up a timeout for subscription initialization
Cancellable timeoutWaitingForConnectionAckMessage = null;
if (connectionInitializationTimeout != null) {
timeoutWaitingForConnectionAckMessage = Uni.createFrom().item(1).onItem().delayIt().by(Duration.ofMillis(connectionInitializationTimeout)).subscribe().with(timeout -> {
initializationEmitter.fail(new InvalidResponseException("Server did not send a connection_ack message"));
webSocket.close((short) 1002, "Timeout waiting for a connection_ack message");
});
}
// make an effectively final copy of this value to use it in a lambda expression
Cancellable finalTimeoutWaitingForConnectionAckMessage = timeoutWaitingForConnectionAckMessage;
webSocket.handler(text -> {
if (log.isTraceEnabled()) {
log.trace("<<< " + text);
}
try {
JsonObject message = parseIncomingMessage(text.toString());
MessageType messageType = getMessageType(message);
switch(messageType) {
case PING:
send(webSocket, pongMessage);
break;
case CONNECTION_ACK:
// TODO: somehow protect against this being invoked multiple times?
if (finalTimeoutWaitingForConnectionAckMessage != null) {
finalTimeoutWaitingForConnectionAckMessage.cancel();
}
initializationEmitter.complete(null);
break;
case NEXT:
handleData(message.getString("id"), message.getJsonObject("payload"));
break;
case ERROR:
handleOperationError(message.getString("id"), message.getJsonArray("payload"));
break;
case COMPLETE:
handleComplete(message.getString("id"));
break;
case CONNECTION_INIT:
case PONG:
case SUBSCRIBE:
break;
}
} catch (JsonParsingException | IllegalArgumentException e) {
log.error("Unexpected message from server: " + text);
// should we fail the operations here?
}
});
});
}
use of io.smallrye.mutiny.subscription.Cancellable in project smallrye-mutiny by smallrye.
the class UniOnItemOrFailureInvokeTest method testCallWithCancellationBeforeEmission.
@Test
public void testCallWithCancellationBeforeEmission() {
AtomicBoolean called = new AtomicBoolean();
AtomicReference<String> res = new AtomicReference<>();
Uni<Object> emitter = Uni.createFrom().emitter(e -> e.onTermination(() -> called.set(true)));
Cancellable cancellable = Uni.createFrom().item("hello").onItemOrFailure().call((s, f) -> emitter).subscribe().with(res::set);
cancellable.cancel();
assertThat(res).hasValue(null);
// noinspection ConstantConditions
assertThat(called).isTrue();
}
use of io.smallrye.mutiny.subscription.Cancellable in project smallrye-mutiny by smallrye.
the class UniOnNotNullItemTest method testCallWithCancellationBeforeEmission.
@Test
public void testCallWithCancellationBeforeEmission() {
AtomicBoolean called = new AtomicBoolean();
AtomicReference<String> res = new AtomicReference<>();
Uni<Object> emitter = Uni.createFrom().emitter(e -> e.onTermination(() -> called.set(true)));
Cancellable cancellable = Uni.createFrom().item("hello").onItem().ifNotNull().call(s -> emitter).subscribe().with(res::set);
cancellable.cancel();
assertThat(res).hasValue(null);
assertThat(called).isTrue();
}
use of io.smallrye.mutiny.subscription.Cancellable in project smallrye-mutiny by smallrye.
the class UniOnFailureInvokeTest method testCancellationBeforeActionCompletes.
@Test
public void testCancellationBeforeActionCompletes() {
AtomicBoolean terminated = new AtomicBoolean();
Uni<Object> uni = Uni.createFrom().emitter(e -> e.onTermination(() -> terminated.set(true)));
AtomicInteger result = new AtomicInteger();
AtomicReference<Throwable> failed = new AtomicReference<>();
Cancellable cancellable = failure.onFailure().call(i -> uni).subscribe().with(result::set, failed::set);
cancellable.cancel();
assertThat(result).hasValue(0);
assertThat(failed).hasValue(null);
// noinspection ConstantConditions
assertThat(terminated).isTrue();
}
Aggregations