Scala 检测到背压正在发生

Scala 检测到背压正在发生,scala,akka,akka-stream,akka-http,Scala,Akka,Akka Stream,Akka Http,我的Akka HTTP应用程序通过服务器发送的事件流式传输一些数据,客户端可以请求超出其处理能力的事件。代码看起来像这样 complete { source.filter(predicate.isMatch) .buffer(1000, OverflowStrategy.dropTail) .throttle(20, 1 second) .map { evt => ServerSentEvent(evt) } } 有没有一种方法可以检测一个阶段的背压并以某种方式通知

我的Akka HTTP应用程序通过服务器发送的事件流式传输一些数据,客户端可以请求超出其处理能力的事件。代码看起来像这样

complete {
  source.filter(predicate.isMatch)
   .buffer(1000, OverflowStrategy.dropTail)
   .throttle(20, 1 second)
   .map { evt => ServerSentEvent(evt) }
}

有没有一种方法可以检测一个阶段的背压并以某种方式通知客户端,最好使用相同的接收器(通过发出不同类型的输出),或者如果不可能,只让Akka framework调用某种回调,通过控制端通道处理这一事实?

因此,我不确定我是否理解您的用例。您是在询问
.buffer
.throttle
处的背压吗?我的困惑的另一部分是,您建议在水流已经背压的情况下释放一个新的“控制”元素。因此,您的控制元素可能在一段时间内无法接收。此外,如果每次收到背压时都发射控制图元,则可能会创建大量控制图元

构建这个(过于天真的)解决方案的一种方法是使用

要将其转化为更有用的示例,您可以:

  • 内部进行某种调用。合并
    (然后删除其中一个元素)。但要小心不要做任何阻挡的事情。也许只是发送一条可以在其他地方消除重复的信息

  • 写一封信。做这样简单的事情不会太难


  • 不过,我想我必须对用例有更多的了解。看看所有现成的,看看其中一个是否有用。

    我想解决方案是实现我自己的缓冲区,它使用
    合并
    ,并发出带有某种节流的控制元素
    
      val simpleSink: Sink[String, Future[Done]] =
        Sink.foreach(e => println(s"simple: $e"))
    
      val cycleSource: Source[String, NotUsed] =
        Source.cycle(() => List("1", "2", "3", "4").iterator).throttle(5, 1.second)
    
      val conflateFlow: Flow[String, String, NotUsed] =
        Flow[String].conflate((a, b) => {
          "BACKPRESSURE CONTROL ELEMENT"
        })
    
      val backpressureFlow: Flow[String, String, NotUsed] =
        Flow[String]
          .buffer(10, OverflowStrategy.backpressure) throttle (2, 1.second)
    
      val backpressureTest =
        cycleSource.via(conflateFlow).via(backpressureFlow).to(simpleSink).run()