在 Quarkus Websocket 中阻塞 IO 线程

Blocking IO Thread in Quarkus Websocket

我有一个接收数据的 websocket,我想用这些数据做一些数据库操作。这是我的代码的简化版本:

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Event;
import javax.inject.Inject;
import javax.websocket.OnMessage;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/my_socket")
@ApplicationScoped
public class MySocket {

  @Inject
  Event<MySocketMessage> messageEvent;

  @OnMessage
  public void onMessage(String message) {
    messageEvent.fire(new MySocketMessage(message));
  }
}
public class MySocketMessage {

  private final String message;

  public MySocketMessage(String message) {
    this.message = message;
  }

  public String getMessage() {
    return this.message;
  }
}
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.persistence.EntityManager;

@ApplicationScoped
public class MyDatabaseHandler {

  @Inject
  EntityManager entityManager;

  public void handleMessage(@Observes MySocketMessage message) {
    // Do some blocking database operations
    Object entity = new Object(message.getMessage());
    entityManager.persist(entity);
  }
}

在单元测试中执行这段代码没有问题。但是当我 运行 应用程序时,我得到这个异常:

2021-07-27 15:35:14,667 ERROR [ch.scs.mbv.veg.web.ScannerSocket] (vert.x-eventloop-thread-7) The my socket encountered the following error: : java.lang.IllegalStateException: You have attempted to perform a blocking operation on a IO thread. This is not allowed, as blocking the IO thread will cause major performance issues with your application. If you want to perform blocking EntityManager operations make sure you are doing it from a worker thread.
        at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.checkBlocking(TransactionScopedSession.java:110)
        at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.persist(TransactionScopedSession.java:134)
        at io.quarkus.hibernate.orm.runtime.session.ForwardingSession.persist(ForwardingSession.java:53)
        at
...

我知道我不应该在 IO 线程上执行阻塞操作,但我不关心程序的性能,因为它只有一个用户。这也是我没有(也不想)让它响应的原因。快速搜索显示这里已经回答了一个非常相似的问题:blocking EntityManager operations 因此,我尝试在我的代码中的多个位置放置 @Blocking 注释,但这根本没有任何效果,异常不断弹出。我错过了什么?任何帮助将不胜感激!!!

经过大量查找,发现是Quarkus 1.13.3版本的bug导致了这个错误。我没有找到使用此版本解决问题的方法。然而,切换到2.1.2版本解决了这个问题!

除了切换到较新的版本,我还必须在文件 application.properties 中添加以下两行:

quarkus.websocket.dispatch-to-worker=true
quarkus.quartz.start-mode=forced

仅当项目中某处使用 Quartz 时才需要第二行。