use of io.smallrye.mutiny.Uni in project hibernate-reactive by hibernate.
the class MultipleContextTest method testFindWithMutiny.
@Test
public void testFindWithMutiny(TestContext testContext) {
final Async async = testContext.async();
Uni<Mutiny.Session> sessionUni = getMutinySessionFactory().openSession();
currentSession = sessionUni;
Context testVertxContext = Vertx.currentContext();
// Create a different new context
Context newContext = Vertx.vertx().getOrCreateContext();
Assertions.assertThat(testVertxContext).isNotEqualTo(newContext);
test(testContext, sessionUni.invoke(session -> {
// Run test in the new context
newContext.runOnContext(event -> test(async, testContext, session.find(Competition.class, "Chess boxing").onItemOrFailure().transformToUni((unused, e) -> Uni.createFrom().completionStage(assertExceptionThrown(e)))));
}));
}
use of io.smallrye.mutiny.Uni in project smallrye-reactive-messaging by smallrye.
the class AbstractMediator method invokeBlocking.
@SuppressWarnings("unchecked")
protected <T> Uni<T> invokeBlocking(Message<?> message, Object... args) {
try {
Optional<LocalContextMetadata> metadata = message != null ? message.getMetadata().get(LocalContextMetadata.class) : Optional.empty();
Context currentContext = metadata.map(m -> Context.newInstance(m.context())).orElseGet(Vertx::currentContext);
return workerPoolRegistry.executeWork(currentContext, Uni.createFrom().emitter(emitter -> {
try {
Object result = this.invoker.invoke(args);
if (result instanceof CompletionStage) {
((CompletionStage<?>) result).thenAccept(x -> emitter.complete((T) x));
} else {
emitter.complete((T) result);
}
} catch (RuntimeException e) {
log.methodException(configuration().methodAsString(), e);
emitter.fail(e);
}
}), configuration.getWorkerPoolName(), configuration.isBlockingExecutionOrdered());
} catch (RuntimeException e) {
log.methodException(configuration().methodAsString(), e);
throw e;
}
}
use of io.smallrye.mutiny.Uni in project smallrye-reactive-messaging by smallrye.
the class MutinyEmitterImpl method send.
@Override
@CheckReturnValue
public Uni<Void> send(T payload) {
if (payload == null) {
throw ex.illegalArgumentForNullValue();
}
// If we are running on a Vert.x I/O thread, we need to capture the context to switch back
// during the emission.
Context context = Vertx.currentContext();
Uni<Void> uni = Uni.createFrom().emitter(e -> emit(ContextAwareMessage.of(payload).withAck(() -> {
e.complete(null);
return CompletableFuture.completedFuture(null);
}).withNack(reason -> {
e.fail(reason);
return CompletableFuture.completedFuture(null);
})));
if (context != null) {
uni = uni.emitOn(runnable -> context.runOnContext(x -> runnable.run()));
}
return uni;
}
use of io.smallrye.mutiny.Uni in project smallrye-reactive-messaging by smallrye.
the class MutinyEmitterInjectionTest method testWithPayloadsAndAckComingBackOnSameEventLoop.
@Test
public void testWithPayloadsAndAckComingBackOnSameEventLoop() {
final MyBeanEmittingPayloadsWithAck bean = installInitializeAndGet(MyBeanEmittingPayloadsWithAck.class);
List<Uni<Void>> unis = new CopyOnWriteArrayList<>();
assertThat(bean.emitter()).isNotNull();
Vertx vertx = Vertx.vertx();
Context context = vertx.getOrCreateContext();
context.runOnContext(x -> unis.add(bean.emitter().send("a")));
AtomicReference<Context> reference = new AtomicReference<>();
await().until(() -> unis.size() == 1);
unis.get(0).invoke(x -> reference.set(Vertx.currentContext())).await().indefinitely();
assertThat(reference.get()).isEqualTo(context);
context = ((VertxInternal) vertx).createEventLoopContext();
context.runOnContext(x -> unis.add(bean.emitter().send("b")));
await().until(() -> unis.size() == 2);
unis.get(1).invoke(x -> reference.set(Vertx.currentContext())).await().indefinitely();
assertThat(reference.get()).isEqualTo(context);
}
use of io.smallrye.mutiny.Uni 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?
}
});
});
}
Aggregations