在Play Framework中处理阻止IO调用

看看下面的两个类,哪个是建议的,它们又有什么不同?。

// Approach 1
public class Test extends Controller {
    private final DatabaseExecutionContext executionContext;

    @Inject
    public Test(DatabaseExecutionContext executionContext) {
        this.executionContext = executionContext;
    }

    public CompletableFuture<Result> get() throws ExecutionException,InterruptedException {

        return io().thenApply(Results::ok);
    }

    public CompletableFuture<String> io() throws ExecutionException,InterruptedException {
        return CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "io";
        },executionContext);

    }
}
//Approach 2
public class Test extends Controller {
    private final DatabaseExecutionContext executionContext;

    @Inject
    public Test(DatabaseExecutionContext executionContext) {
        this.executionContext = executionContext;
    }

    public Result get() throws ExecutionException,InterruptedException {

        return Results.ok(io());
    }

    public String io() throws ExecutionException,executionContext).join();

    }
}

游戏对我来说是新手,我想了解如何正确处理阻塞的IO调用。 有人可以解释一下Play框架如何使用Completable Future,以我的观点,它仍然处于阻塞状态并且没有太大意义,并使我的代码处理的CompletableFuture本身就很可怕。

zas135421 回答:在Play Framework中处理阻止IO调用

Play is new to me,I want to understand how to properly handle blocking IO calls.

嗨!好问题。我一直在使用Play!现在有一段时间了,我认为您偶然发现了Play最复杂的问题之一!必须提供。让我们使用官方Play!回答您问题的文档:

为异步控制器调整了默认配置。换句话说,应用代码应避免在控制器中阻塞,即,使控制器代码等待操作。此类阻止操作的常见示例是JDBC调用,流API,HTTP请求和长计算。 [1]

因此回答您的问题:轻松根本不使用阻塞呼叫。 :)如果您仍然想阻止通话,请继续阅读。

Can someone explain how Play framework uses Completable Future,in my point of view it's still blocking and does not make much sense and making my code deal with CompletableFuture which itself is horrible.

您提供的两个示例确实都是阻塞的。它们之间只有一点点差异。具有CompletableFuture的get()方法将立即退出,而没有get()方法的CompletableFuture将不会退出。它将等待阻塞调用完成。 第一个将发布Play!资源来做其他事情,例如处理其他请求。

由于您正在执行阻塞呼叫,您可能需要针对如何处理呼叫制定策略:

从下至上,

Play框架是一个异步Web框架。流是使用迭代器异步处理的。由于play-core中的IO永远不会阻塞,因此Play中的线程池已调整为使用比传统Web框架更少的线程。

因此,如果您打算编写阻塞的IO代码或可能执行大量CPU密集型工作的代码,则需要确切知道哪个线程池正在承担该工作量,并且需要相应地对其进行调整。不考虑这一点而进行阻塞IO可能会导致Play Framework的性能非常差,例如,您可能只看到每秒处理几个请求,而CPU使用率为5%。相比之下,典型开发硬件(例如MacBook Pro)上的基准测试表明Play能够在正确调整的情况下每秒处理数百甚至数千个请求的工作负载。 [2]

同样,这里的文档可帮助您设计此策略:Best practices for ThreadPools

如果您的应用具有超高同步性,您就可以忘记CompletableFuture方法,而使用此处描述的方法:https://www.playframework.com/documentation/2.8.x/ThreadPools#Highly-synchronous

本文链接:https://www.f2er.com/2852897.html

大家都在问