Search in sources :

Example 16 with Cancellable

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);
}
Also used : Cancellable(io.smallrye.mutiny.subscription.Cancellable) ArrayList(java.util.ArrayList) Test(org.junit.jupiter.api.Test)

Example 17 with Cancellable

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?
            }
        });
    });
}
Also used : WebSocketSubprotocolHandler(io.smallrye.graphql.client.vertx.websocket.WebSocketSubprotocolHandler) Logger(org.jboss.logging.Logger) CompletableFuture(java.util.concurrent.CompletableFuture) Uni(io.smallrye.mutiny.Uni) JsonValue(javax.json.JsonValue) ResponseReader(io.smallrye.graphql.client.impl.ResponseReader) OperationIDGenerator(io.smallrye.graphql.client.vertx.websocket.opid.OperationIDGenerator) Duration(java.time.Duration) Map(java.util.Map) Json(javax.json.Json) InvalidResponseException(io.smallrye.graphql.client.InvalidResponseException) JsonObject(javax.json.JsonObject) GraphQLClientException(io.smallrye.graphql.client.GraphQLClientException) MultiEmitter(io.smallrye.mutiny.subscription.MultiEmitter) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) JsonArray(javax.json.JsonArray) UniEmitter(io.smallrye.mutiny.subscription.UniEmitter) WebSocket(io.vertx.core.http.WebSocket) Collectors(java.util.stream.Collectors) JsonString(javax.json.JsonString) IncrementingNumberOperationIDGenerator(io.smallrye.graphql.client.vertx.websocket.opid.IncrementingNumberOperationIDGenerator) List(java.util.List) StringReader(java.io.StringReader) GraphQLError(io.smallrye.graphql.client.GraphQLError) Cancellable(io.smallrye.mutiny.subscription.Cancellable) JsonParsingException(javax.json.stream.JsonParsingException) JsonObjectBuilder(javax.json.JsonObjectBuilder) Cancellable(io.smallrye.mutiny.subscription.Cancellable) JsonObject(javax.json.JsonObject) InvalidResponseException(io.smallrye.graphql.client.InvalidResponseException) JsonParsingException(javax.json.stream.JsonParsingException)

Example 18 with Cancellable

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();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Cancellable(io.smallrye.mutiny.subscription.Cancellable) AtomicReference(java.util.concurrent.atomic.AtomicReference) Test(org.junit.jupiter.api.Test)

Example 19 with Cancellable

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();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Cancellable(io.smallrye.mutiny.subscription.Cancellable) AtomicReference(java.util.concurrent.atomic.AtomicReference) Test(org.junit.jupiter.api.Test)

Example 20 with Cancellable

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();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Cancellable(io.smallrye.mutiny.subscription.Cancellable) AtomicReference(java.util.concurrent.atomic.AtomicReference) Test(org.junit.jupiter.api.Test)

Aggregations

Cancellable (io.smallrye.mutiny.subscription.Cancellable)26 Test (org.junit.jupiter.api.Test)17 AtomicReference (java.util.concurrent.atomic.AtomicReference)11 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)9 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)8 Uni (io.smallrye.mutiny.Uni)5 IOException (java.io.IOException)5 Duration (java.time.Duration)4 UniEmitter (io.smallrye.mutiny.subscription.UniEmitter)3 CompletableFuture (java.util.concurrent.CompletableFuture)3 GraphQLClientException (io.smallrye.graphql.client.GraphQLClientException)2 GraphQLError (io.smallrye.graphql.client.GraphQLError)2 InvalidResponseException (io.smallrye.graphql.client.InvalidResponseException)2 ResponseReader (io.smallrye.graphql.client.impl.ResponseReader)2 WebSocketSubprotocolHandler (io.smallrye.graphql.client.vertx.websocket.WebSocketSubprotocolHandler)2 IncrementingNumberOperationIDGenerator (io.smallrye.graphql.client.vertx.websocket.opid.IncrementingNumberOperationIDGenerator)2 OperationIDGenerator (io.smallrye.graphql.client.vertx.websocket.opid.OperationIDGenerator)2 MultiEmitter (io.smallrye.mutiny.subscription.MultiEmitter)2 WebSocket (io.vertx.core.http.WebSocket)2 StringReader (java.io.StringReader)2