-1

这是我目前的实现HttpService.serve()

@Override
public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
    return HttpResponse.from(req.aggregate().thenApply(ahr -> {
        MyResponse myResponse = Utils.handle(ahr);
        HttpResponse httpResponse Utils.toResponse(myResponse);
        return httpResponse; 
    }));
}

我有一个用户定义的响应延迟,它可能因每个单独的请求响应而异,这在myResponse对象中可用。

以非阻塞方式应用此延迟的最佳方法是什么,我可以看到一些delayAPI-s 但它们在HttpResponse. 任何有关流式 API 设计或装饰器的额外提示或指针都会有所帮助。我真的从 Armeria 代码库中学到了很多东西 :)

4

1 回答 1

1

如果您甚至在使用请求正文之前就知道所需的延迟,您可以简单地使用HttpResponse.delayed()

@Override
public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
    return HttpResponse.delayed(
        HttpResponse.of(200),
        Duration.ofSeconds(3),
        ctx.eventLoop());
}

如果您需要消费内容或执行一些操作来计算所需的延迟,您可以结合HttpResponse.delayed()使用HttpResponse.from()

@Override
public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
    return HttpResponse.from(req.aggregate().thenApply(ahr -> {
    //                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        MyResponse myResponse = Utils.handle(ahr);
        HttpResponse httpResponse = Utils.toResponse(myResponse);
        Duration myDelay = Utils.delayMillis(...);
        return HttpResponse.delayed(httpResponse, myDelay, ctx.eventLoop());
        //                  ^^^^^^^
    });
}

如果延迟实际上不是延迟而是等待某事发生,您可以使用CompletableFuture.thenCompose()更强大的:

@Override
public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
    return HttpResponse.from(req.aggregate().thenCompose(ahr -> {
    //                                       ^^^^^^^^^^^
        My1stResponse my1stRes = Utils.handle(ahr);

        // Schedule some asynchronous task that returns another future.
        CompletableFuture<My2ndResponse> myFuture = doSomething(my1stRes);

        // Map the future into an HttpResponse.
        return myFuture.thenApply(my2ndRes -> {
            HttpResponse httpRes = Utils.toResponse(my1stRes, my2ndRes);
            return httpRes;
        });
    });
}

对于更复杂的工作流程,我建议您查看 Reactive Streams 实现,例如 Project Reactor 和 RxJava,它们提供了避免回调地狱的工具。

于 2020-11-10T11:50:20.993 回答