当前位置: 首页 > 知识库问答 >
问题:

quarkus:IllegalStateException:您试图在IO线程上执行阻止操作。这是不允许的,因为阻塞IO线程

伏德义
2023-03-14

夸克有一件事我很难理解。我在Oracle中使用JPA。因此,我有错误IllegalStateExcema:您试图在IO线程上执行阻塞操作。这是不允许的,因为阻塞了IO线程,我在QUUKUS文档中查看了如何在没有这个困难的情况下进行JPA调用。但是所有的例子和文档都使用PostgreSQL或MariaDB与响应客户端。但是我没有找到任何用于经典JDBC客户端的客户端。

我找到了一个部分有效的解决方案。

Uni.cretaFrom().Items(() -> MyBlokingIOCall());

事实上,我不再有例外。但是MyBlokingIOCall方法可能引发异常。我想我可以使用Uni的onFailure,但我们不能将引发异常的方法传递给

Uni.cretaFrom().Items

事实上,该方法作为一个供应商的参数,因此必须捕获异常。在这个解决方案中使用Uni的onFailure是不可能的。如果我在命令式模式下使用当前代码

try {
   Response.ok (myService ());
} catch (throwable e) {
   Response.status (555, e.getMessage ());
}

我试图以被动的形式这样做,但没有找到解决办法。我没有找到任何帮助。我想象了一些像。

Uni.createFrom().Items(() -> myService())
.onItem().apply(data -> Response.ok(data))
.onFailure().apply(err -> Response.status(555, err.getMessage()))

但是这会导致编译错误。事实上,方法myService不能在供应商中使用,因为它抛出了一个异常。因此必须捕获它。但是我们不再进入Uni的onFailure,我们无法跟踪我们捕获的错误。

我觉得我想得太多了,不想换一种思维方式,而是想穿上我的命令式代码。

但我找不到一个文件或例子,看起来像这样的任何方式。我想象有一种做事的方式(如果没有夸克,夸克斯就不存在)。我认为,当你用正确的方法思考问题时,你必须找到医生,但当你不知道该去哪里时,情况就更复杂了。我没有找到它,因为我不知道我在找什么。

我想我必须封装JPA调用,它产生一个Uni或Multi,处理器使用它将实体转换为DTO,然后传输到资源Rest层,后者将DTO转换为响应。JPA调用必须能够对处理器和资源层产生错误

因此,有必要在每一步捕获这些错误,以便通过统一或多重传播它们

但是怎么做呢?

共有2个答案

芮朗
2023-03-14

我更改了myService方法,以便它返回供应商并处理异常

   public Supplier<List<String>> myService (String arg){
      return () -> {
         try {
            //my code
            return result;
         } catch (Exception e) {
            throw new RuntimeException(e);
         }
      };
   }

我这样称呼它

Uni.createFrom().item(myService("sample")))
.onItem().apply(data -> Response.ok(data))
.onFailure().recoverWithItem(err -> Response.status(600, err.getMessage()))
.onItem().apply(ResponseBuilder::build)
.emitOn(Infrastructure.getDefaultExecutor())
澹台臻
2023-03-14

通过简单地提供lambda实现(或方法引用)作为方法调用参数,在简洁性和第一期望方面,这是一种已知lambda限制。

同时,它可以通过围绕预期的功能接口实现扩展来简单地解决,在您的情况下,它将是供应商

/**
 * A Supplier sub-interface that catches any thrown exception
 * and translates to an unchecked one.
 *
 * <p>This is a functional interface whose functional method is
 * {@link #getChecked()}.
 */
@FunctionalInterface
public interface CheckedSupplier<T> extends Supplier<T> {

    @Override
    default T get() {
        try {
            return getChecked();
        } catch (final Exception e) {
            // Your common exception handling logic here..
            throw new RuntimeException(e);
        }
    }

    /**
     * Gets a result.
     *
     * @return a result
     * @throws Exception
     */
    T getChecked() throws Exception;
}

请注意,函数接口签名不再是#get(),而是#getChecked()。但这对编译器没有影响,编译器将尝试根据预期的函数签名检查函数签名,即:

返回T型对象的方法

然后,只要在供应商所在的位置使用显式转换,就可以简单地使用新的CheckedSupplier接口

Uni.createFrom().item((CheckedSupplier<DataType>) MutinyTest::findOne)
      .onItem()
      .apply(i-> Response.ok(i))
      .onFailure()
      .apply(e-> Response.status(555, e.getMessage()));

 类似资料:
  • 问题内容: 我有一个在后台运行的线程正在以阻塞方式从输入设备读取事件,现在当我退出应用程序时,我想正确清理线程,但是我不能只运行pthread_join(),因为该线程由于IO阻塞而永远不会退出。 我如何正确解决这种情况?我应该发送一个pthread_kill(theard,SIGIORM)还是一个pthread_kill(theard,SIGALRM)来中断该块?那两个信号是否正确?还是有另一种

  • 在Java中,线程可以有不同的状态: 新建、可运行、阻止、等待、定时等待、终止 但是,当线程被IO阻塞时,其状态为“RUNNABLE”。我如何判断它是否被IO阻止?

  • 非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 ServletInputStream.setReadListener 或ServletOutputStream.setWriteListener 方法时将抛出IllegalStateException。为了支持在 Ser

  • Web 容器中的非阻塞请求处理有助于提高对改善 Web 容器可扩展性不断增加的需求,增加 Web 容器可同时处理请求的连接数量。servlet 容器的非阻塞 IO 允许开发人员在数据可用时读取数据或在数据可写时写数据。非阻塞 IO 仅对在 Servlet 和 Filter(2.3.3.3节定义的,“异步处理”)中的异步请求处理和升级处理(2.3.3.5节定义的,“升级处理”)有效。否则,当调用 S

  • Go提供的网络接口,在用户层是阻塞的,这样最符合人们的编程习惯。在runtime层面,是用epoll/kqueue实现的非阻塞io,为性能提供了保障。 如何实现 底层非阻塞io是如何实现的呢?简单地说,所有文件描述符都被设置成非阻塞的,某个goroutine进行io操作,读或者写文件描述符,如果此刻io还没准备好,则这个goroutine会被放到系统的等待队列中,这个goroutine失去了运行权

  • 问题内容: 我不是Node程序员,但我对 单线程无阻塞IO模型的 工作方式感兴趣。在阅读了理解理解节点事件循环文章之后,我对此感到非常困惑。它给出了该模型的示例: 队列: 由于只有一个线程,所以有两个请求A(首先出现)和B(首先出现),服务器端程序将首先处理请求A:执行SQL查询是代表I / O等待的sleeping语句。并且该程序被困在等待中,并且无法执行使网页落后的代码。在等待期间程序会切换到