Scala 如何摆脱;额外的;阿克卡河流量阶段的未来?
我正在使用Akka Streams,并尝试使用Scala 如何摆脱;额外的;阿克卡河流量阶段的未来?,scala,akka,akka-stream,Scala,Akka,Akka Stream,我正在使用Akka Streams,并尝试使用Flowstages来最有效地描述整个图形。在某些阶段,我通过ask模式向参与者发送消息 当然,当我使用ask模式时,我需要使用mapTo,以获得进一步处理所需的类型 以下是一个例子: val runnableGraph = Source.single(CheckEntity(entity)) .map { check => (postgresActor ? check) .mapTo[CheckEntityResult
Flow
stages来最有效地描述整个图形。在某些阶段,我通过ask
模式向参与者发送消息
当然,当我使用ask
模式时,我需要使用mapTo
,以获得进一步处理所需的类型
以下是一个例子:
val runnableGraph = Source.single(CheckEntity(entity))
.map { check =>
(postgresActor ? check)
.mapTo[CheckEntityResult]
.map {
case failure: PostgresFailure => Left(failure.message)
case pEntity: PEntity => Right(check)
}
}
.map {
_.map {
case Left(msg) => Future(Left(msg))
case Right(check) =>
(redisActor ? pEntity)
.mapTo[CheckEntityResult]
.map {
case failure: RedisFailure => Left(failure.message)
case rEntity: REntity => Right(rEntity)
}
}
}
.toMat(Sink.head)(Keep.right)
//The result's type is Future[Future[Either[String, Entity]]]
val futureResult = runnableGraph.run()
如何摆脱阶段之间嵌套的
Future
?一个使通过流传播CheckEntity
元素更容易的方法是更改CheckEntityResult
类以包含相应的CheckEntity
实例。这看起来像这样:
abstract class CheckEntityResult(entity: CheckEntity) extends Entity
case class PEntity(entity: CheckEntity) extends CheckEntityResult(entity)
case class PostgresFailure(entity: CheckEntity, message: String) extends CheckEntityResult(entity)
case class REntity(entity: CheckEntity) extends CheckEntityResult(entity)
case class RedisFailure(entity: CheckEntity, message: String) extends CheckEntityResult(entity)
然后,在调整参与者以处理这些消息后,您可以使用和mapsync
(根据需要调整并行级别)与参与者交互,并避免物化值中嵌套的Future
:
implicit val askTimeout = Timeout(5.seconds)
val runnableGraph = Source.single(CheckEntity(entity))
.ask[CheckEntityResult](parallelism = 3)(postgresActor)
.map {
case PostgresFailure(_, msg) => msg
case PEntity(e) => e
}
.mapAsync(parallelism = 3) {
case failureMsg: String => Future.successful(failureMsg)
case e: CheckEntity => (redisActor ? e).mapTo[CheckEntityResult]
}
.map {
case failureMsg: String => Left(failureMsg)
case RedisFailure(_, msg) => Left(msg)
case r: REntity => Right(r)
}
.toMat(Sink.head)(Keep.right)
val futureResult = runnableGraph.run() // Future[Either[String, Entity]]
使通过流传播
CheckEntity
元素更容易的一个方法是将CheckEntityResult
类更改为包含相应的CheckEntity
实例。这看起来像这样:
abstract class CheckEntityResult(entity: CheckEntity) extends Entity
case class PEntity(entity: CheckEntity) extends CheckEntityResult(entity)
case class PostgresFailure(entity: CheckEntity, message: String) extends CheckEntityResult(entity)
case class REntity(entity: CheckEntity) extends CheckEntityResult(entity)
case class RedisFailure(entity: CheckEntity, message: String) extends CheckEntityResult(entity)
然后,在调整参与者以处理这些消息后,您可以使用和mapsync
(根据需要调整并行级别)与参与者交互,并避免物化值中嵌套的Future
:
implicit val askTimeout = Timeout(5.seconds)
val runnableGraph = Source.single(CheckEntity(entity))
.ask[CheckEntityResult](parallelism = 3)(postgresActor)
.map {
case PostgresFailure(_, msg) => msg
case PEntity(e) => e
}
.mapAsync(parallelism = 3) {
case failureMsg: String => Future.successful(failureMsg)
case e: CheckEntity => (redisActor ? e).mapTo[CheckEntityResult]
}
.map {
case failureMsg: String => Left(failureMsg)
case RedisFailure(_, msg) => Left(msg)
case r: REntity => Right(r)
}
.toMat(Sink.head)(Keep.right)
val futureResult = runnableGraph.run() // Future[Either[String, Entity]]
可以考虑将您的Actudio查询转换为<代码>流以及<代码> MAPASYNC (具有适当的并行性):
使用转换后的流,您的runnableGraph可以按如下方式进行组装,结果类型为Future[other[]]
:
val runnableGraph = Source.single(CheckEntity(entity))
.via(postgresCheckFlow(parallelism))
.via(redisCheckFlow(parallelism))
...
可以考虑将您的Actudio查询转换为<代码>流以及<代码> MAPASYNC (具有适当的并行性):
使用转换后的流,您的runnableGraph可以按如下方式进行组装,结果类型为Future[other[]]
:
val runnableGraph = Source.single(CheckEntity(entity))
.via(postgresCheckFlow(parallelism))
.via(redisCheckFlow(parallelism))
...
谢谢答案真的很全面!谢谢答案真的很全面!非常感谢在撰写之前在不同阶段分解图表的想法:)非常感谢在撰写之前在不同阶段分解图表的想法:)