我正在使用Akka流和Akka HTTP构建数据管道。用例非常简单,接收来自用户的Web请求,该请求将执行两项操作。首先通过调用第三方API创建会话,然后将此会话提交到某个持久存储,当我们收到会话时,它将代理原始用户请求但添加会话数据。
我已经开始处理数据管道的第一个分支,即会话处理,但我想知道是否有更优雅的方法将第3方API的HTTP响应解组为当前我正在使用的POJO Jackson.unmarshaller.unmarshal
返回CompletionStage<T>
,然后我必须将其展开到T
。它不是很优雅,我猜测Akka HTTP有更聪明的方法来做到这一点。
这是我现在的代码
private final Source<Session, NotUsed> session =
Source.fromCompletionStage(
getHttp().singleRequest(getSessionRequest(), getMat())).
map(r -> Jackson.unmarshaller(Session.class).unmarshal(r.entity(), getMat())).
map(f -> f.toCompletableFuture().get()).
alsoTo(storeSession);
答案 0 :(得分:1)
Akka Streams为您提供mapAsync
,这是一个以可配置的非阻塞方式处理管道中异步计算的阶段。
您的代码应该变成
Source.fromCompletionStage(
getHttp().singleRequest(getSessionRequest(), getMat())).
mapAsync(4, r -> Jackson.unmarshaller(Session.class).unmarshal(r.entity(), getMat())).
alsoTo(storeSession);
请注意:
CompletableFuture.get
是一个阻止呼叫。这可能会在您的管道中造成可怕的问题。Int
所需的mapAsync
参数(并行性)允许微调同时运行多少并行异步操作。 mapAsync
中可以找到<a th:href="@{/user/map(userId=${user.id},mapId=${map.id})}">
中的更多信息。