Spring 引导控制器返回 scala.concurrent.Future 的单声道
Spring Boot Controller returning a Mono of a scala.concurrent.Future
我是运行 Spring 引导应用程序中的Akka actor 系统。我有一组演员 运行.
从我的控制器 class 我调用我的服务 class,它使用 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
return 是 scala.concurrent.Future<SportEventDetails>
而我找不到将 scala Future 转换为 Java CompletableFuture<SportEventDetails>
的方法或 CompletionStage<SportEventDetails>
.
所以,我的问题是:在使用 Akka 的 Patterns.ask(...) 模型时,我如何 return 向客户 SportEventDetails
表示 json ?
Future
、Mono
和 CompletionStage
是同一概念的三个实现,一个值可能存在也可能不存在。您将需要一种方法将它们转换为相同的类型,然后需要一种方法 "flatten" 嵌套类型。 Mono.fromCompletionStage
是一种将 CompletionStage
转换为 Mono
.
的方法
最简单的方法是避免 Future
和完全扁平化:
在较新的 Java 版本(2.5.19 或更高版本)中:
有 ask
重载占用 java.time.Duration
超时,您将获得 return 值 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
侦听未来并完成目标类型的实例。
我是运行 Spring 引导应用程序中的Akka actor 系统。我有一组演员 运行.
从我的控制器 class 我调用我的服务 class,它使用 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
return 是 scala.concurrent.Future<SportEventDetails>
而我找不到将 scala Future 转换为 Java CompletableFuture<SportEventDetails>
的方法或 CompletionStage<SportEventDetails>
.
所以,我的问题是:在使用 Akka 的 Patterns.ask(...) 模型时,我如何 return 向客户 SportEventDetails
表示 json ?
Future
、Mono
和 CompletionStage
是同一概念的三个实现,一个值可能存在也可能不存在。您将需要一种方法将它们转换为相同的类型,然后需要一种方法 "flatten" 嵌套类型。 Mono.fromCompletionStage
是一种将 CompletionStage
转换为 Mono
.
最简单的方法是避免 Future
和完全扁平化:
在较新的 Java 版本(2.5.19 或更高版本)中:
有 ask
重载占用 java.time.Duration
超时,您将获得 return 值 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
侦听未来并完成目标类型的实例。