在流的生命周期中缓存已处理的消息

时间:2016-02-01 05:24:36

标签: akka akka-stream akka-http

我正在重做上一个问题,使其更加专注和清晰。 我有以下情况:

case class Hello(u:String) extends A
case class Goodbye extends A
case class GoodbyeAck(u:String) extends B

 val myProcessor: Flow[A, B, Unit] =  Flow[A]
    .map {
      case Hello(u:String) => // I want to cache u (the username)
      case Goodbye => GoodbyeAck(u)
    }

所以,在流的开头我得到一个Hello(用户名),在流的末尾,我收到了一个再见。我想用Goodbye(用户名)回复。

我应该如何缓存用户名(u),以便它可以在流的生命周期内使用,所以我可以在它说再见的时候拥有它?我可以利用一些背景吗?或者我需要在框架外进行吗?

1 个答案:

答案 0 :(得分:1)

这似乎是少数需要可变状态的例子之一。虽然不是“纯粹的功能”,但国家可以通过不允许外部影响但仍然提供您正在寻找的功能的方式进行隔离。

注意:在收到Hello的情况下,您的问题没有指定地图应返回的B值。类型B的值是必要的,因为简单的缓存是Unit类型。因此,flatMapConcat用于符合问题中Flow的要求,即在收到Hello时不返回任何内容:

def cacheProcessor(defaultString : String = "") : Flow[A, B, Unit] = {

  var userCache : String = defaultString

  Flow[A] flatMapConcat {
    case Hello(u : String) => {
      userCache = u
      Source.empty[B]
    }
    case Goodbye => Source.single[B](GoodbyeAck(userCache))
  }
}//end def cacheProcessor

虽然userCache是​​可变状态,但在返回的Flow.flatMapConcat之外无法访问它。一个重要的一点是cacheProcessor必须是def,因此每个Flow都有一个唯一的userCache