使用akka流有条件地跳过流

使用akka流有条件地跳过流,akka,akka-stream,akka-http,Akka,Akka Stream,Akka Http,我使用的是akka流,我有一段图形需要有条件地跳过,因为流无法处理某些值。具体地说,我有一个接受字符串并发出http请求的流,但是当字符串为空时,服务器无法处理这种情况。但是我需要返回一个空字符串。有没有一种方法可以做到这一点,而不必通过http请求知道它将失败?我基本上有: val source = Source("1", "2", "", "3", "4") val httpRequest: Flow[String, HttpRequest, _] val httpResponse: Flo

我使用的是akka流,我有一段图形需要有条件地跳过,因为流无法处理某些值。具体地说,我有一个接受字符串并发出http请求的流,但是当字符串为空时,服务器无法处理这种情况。但是我需要返回一个空字符串。有没有一种方法可以做到这一点,而不必通过http请求知道它将失败?我基本上有:

val source = Source("1", "2", "", "3", "4")
val httpRequest: Flow[String, HttpRequest, _]
val httpResponse: Flow[HttpResponse, String, _]
val flow = source.via(httpRequest).via(httpResponse)

我能想到的唯一一件事就是在我的httpResponse流中捕获400错误并返回一个默认值。但是我希望能够避免为我知道将要失败的请求而点击服务器的开销。

您可以使用
flatMapConcat

(警告:从未编译过,但您将了解其要点)


Viktor Klang的解决方案简洁明了。我只是想用图表来演示另一种方法

您可以将字符串源拆分为两个流,并在一个流中筛选有效字符串,在另一个流中筛选无效字符串。然后合并结果(“”)

根据:


注意:此解决方案会分割流,因此接收器处理字符串值结果的顺序可能与基于输入的预期顺序不同。

您的示例未编译。httpRequest的输出是httpRequest类型,httpResponse的输入是httpResponse类型,因此它们不能用“via”链接在一起。是的!这是另一个选项,当您对操作的重新排序感到满意时(http流和非http流并行运行),这是完美的。我没有想到并行过滤器。关于排序的观点很好,但是akka http的请求流是无序的(至少https池是这样),Viktor可以创建
源代码。每个“过滤器”的单个
会以任何方式对流产生负面影响吗?请原谅我的离题问题,但是
映射({case=>?})
比只
映射{case=>?}
更可取吗?除非有必要(在较长的参数列表中),否则我倾向于不在括号内嵌套大括号。我的前同事过去经常这样做,
({case\u=>???})
,我经常删除多余的paren…当我使用显式点时,我倾向于使用括号。
val source = Source("1", "2", "", "3", "4")
val httpRequest: Flow[String, HttpRequest, _]
val httpResponse: Flow[HttpResponse, String, _]
val makeHttpCall: Flow[HttpRequest, HttpResponse, _]
val someHttpTransformation = httpRequest via makeHttpCall via httpResponse
val emptyStringSource = Source.single("")
val cleanerSource = source.flatMapConcat({
  case "" => emptyStringSource
  case other => Source.single(other) via someHttpTransformation
})
val g = RunnableGraph.fromGraph(FlowGraph.create() { implicit builder: FlowGraph.Builder[Unit] =>
  import FlowGraph.Implicits._

  val source = Source(List("1", "2", "", "3", "4"))
  val sink : Sink[String,_] = ???

  val bcast = builder.add(Broadcast[String](2))
  val merge = builder.add(Merge[String](2))

  val validReq =   Flow[String].filter(_.size > 0)
  val invalidReq = Flow[String].filter(_.size == 0)

  val httpRequest: Flow[String, HttpRequest, _] = ???
  val makeHttpCall: Flow[HttpRequest, HttpResponse, _] = ???
  val httpResponse: Flow[HttpResponse, String, _] = ???
  val someHttpTransformation = httpRequest via makeHttpCall via httpResponse

  source ~> bcast ~> validReq ~> someHttpTransformation ~> merge ~> sink
            bcast ~>      invalidReq                    ~> merge
  ClosedShape
})