我试图调用一个reactive rest,但在这样做的时候,我必须调用它内部的另一个请求,并创建几个文件夹,但quarkus-hibernate-reactive显示下面的错误,什么是最佳实践?
Error:
Caused by: java.lang.IllegalStateException: The current thread cannot be blocked: vert.x-eventloop-thread-2
at io.smallrye.mutiny.operators.UniBlockingAwait.await(UniBlockingAwait.java:29)
我的代码如下:
@POST
@javax.ws.rs.Path("/add")
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
@Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN })
public Uni<Response> addUser(@HeaderParam("userName") String addedBy) throws Exception{
//Here I have one if condition which is checking from database if user exist!
if (checkUser(addedBy).await().indefinitely().intValue() > 0) {
//then creatingfolders
if (createFolders(addedBy) > 0) {
UserBean u = new UserBean(addedBy);
return Uni.createFrom().item(userRepository.addUser(u)).onItem().transform(f -> f != null ? Response.ok(f) : Response.ok(null))
.onItem().transform(ResponseBuilder::build);
}
}
}
public Uni<Long> addUser(UserBean userIN) {
return Panache.withTransaction(userIN::persist)
.replaceWith(userIN.getId());
}
我们如何才能让它等待创建文件夹和检查用户存在的完成?我已经尝试使用@Blocking,但它不起作用。请帮助
3条答案
按热度按时间bksxznpy1#
您应该切换到常规的Hibernate ORM而不是Hibernate Reactive,或者以React式的方式将操作链接在一起。
而不是执行
checkUser(addedBy).await().indefinitely().intValue()
,执行以下操作:koaltpgm2#
你提到你已经试过阻塞注解了,但是你用对了吗?我相信有两种,但只有一种有效。
bvuwiixz3#
这个问题的答案是
runSubscriptionOn
-vertx事件循环线程不允许你在上运行阻塞代码,以避免阻塞事件处理。但只有当你使用await()
或类似的组合时才会发生这种情况,而不是当其他阻塞或昂贵的操作运行时(如阻塞IO操作),在 * 任何一种 * 情况下,你都应该在不同的worker/pool上运行:请注意,您显然需要使用一个延迟项(供应商等),否则您仍然会阻塞事件线程。
另见:https://smallrye.io/smallrye-mutiny/latest/guides/imperative-to-reactive/#running-blocking-code-on-subscription
此外,vertx有一个文件系统模块(你可以在Bean中注入Vertx),它允许你被动地处理文件,所以在这种情况下,你甚至不需要它: