Spring Boot Controller返回一个scala.concurrent.Future的Mono

问题描述 投票:0回答:1

我正在Spring Boot应用程序中运行Akka actor系统。我有一组演员在奔跑。

从我的Controller类中,我调用我的服务类,该服务类使用Actor询问模式,将消息发送给Actor并期望得到响应。下面是服务方法代码:

public Mono<Future<SportEventDetailed>> getEventBySportAndLeagueId(Integer sportId, Integer leagueId) {
    final ActorSelection actorSelection = bootstrapAkka.getActorSystem().actorSelection("/user/some/path");
    final ActorMessage message = new ActorMessage()

    final CompletionStage<Future<SportEventDetails>> futureCompletionStage = actorSelection.resolveOne(Duration.ofSeconds(2))
            .thenApplyAsync(actorRef ->
                        Patterns.ask(actorRef, message, 1000)
                        .map(v1 -> (SportEventDetails) v1, ExecutionContext.global())
                )
                .whenCompleteAsync((sportEventDetailsFuture, throwable) -> {
                    // Here sportEventDetailsFuture is of type scala.concurrent.Future
                    sportEventDetailsFuture.onComplete(v1 -> {
                        final SportEventDetails eventDetails = v1.get();
                        log.info("Thread: {} | v1.get - onComplete - SED: {}", Thread.currentThread(), eventDetails);
                        return eventDetails;
                    }, ExecutionContext.global());
                });

    return Mono.fromCompletionStage(futureCompletionStage);
}

虽然控制器代码很简单

@GetMapping(path = "{sportId}/{leagueId}")
public Mono<Future<SportEventDetails>> getEventsBySportAndLeagueId(@PathVariable("sportId") Integer sportId, @PathVariable("leagueId") Integer leagueId) {
    return eventService.getEventBySportAndLeagueId(sportId, leagueId);
}

[当客户端调用此终结点时,它将获得{"success":true,"failure":false}null(作为字符串)。

[我怀疑null响应的问题是scala.concurrent.Future在发送给客户端之前尚未完成-但我不明白为什么它不能按时完成,因为我认为Mono会等待以供将来完成

这里的问题是Patterns.ask返回一个scala.concurrent.Future<SportEventDetails>,但我找不到将scala Future转换为Java CompletableFuture<SportEventDetails>CompletionStage<SportEventDetails>的方法。

所以,我的问题是:当使用Akka的Patterns.ask(...)模型时,如何向客户端返回SportEventDetails的json表示形式?

java spring scala akka reactor
1个回答
0
投票

FutureMonoCompletionStage是同一概念的三个实现,此处的值可能是也可能不是。您将需要一种将它们转换为相同类型的方法,然后是一种“拉平”嵌套类型的方法。 Mono.fromCompletionStage是将CompletionStage转换为Mono的一种方法。

最简单的是避免完全获取Future和展平:

在较新的Java版本(2.5.19或更高版本中:有ask个重载导致java.time.Duration超时,您将获得CompletionStage<SportEventDetail>的返回值。还有ask重载,它需要一个ActorSelection,因此您不必首先解析,然后再询问解析何时完成:

CompletionStage<SportEventDetail> futureSportEventDetails = 
  Patterns.ask(selection, message, Duration.ofSeconds(3))
return Mono.fromCompletionStage(futureSportEventDetails);

在较旧版本的Akka(我认为是2.4.2和更高版本)中,您应该能够在akka.pattern.PatternsCS中找到相似的签名。

如果您使用的是更高版本,并且无法升级,则可能需要提供自己的转换器方法,从Future<T>CompletionStage<T>Mono<T>,以便将来注册onComplete侦听器并完成一个实例。目标类型。

© www.soinside.com 2019 - 2024. All rights reserved.