Scala 限制流一次处理的元素数量

Scala 限制流一次处理的元素数量,scala,akka,akka-stream,Scala,Akka,Akka Stream,AKKA中的人如何在不删除任何元素的情况下限制流(部分)中当前存在的元素数量?对于AKKA流中的这种情况,我将使用mapsync,小心不要使用.async(与后者一样,至少缺少用于调度任务的自定义Actormatarializer或dispatcher,不会将背压传播得如此紧密) 在这种情况下,机上计数永远不会超过4(一个在第一个mapAsync之前(由于操作员融合),一个在第一个mapAsync中,一个在第二个mapAsync中,一个在第二个mapAsync之后).如果你想在特定阶段限制机上元

AKKA中的人如何在不删除任何元素的情况下限制流(部分)中当前存在的元素数量?

对于AKKA流中的这种情况,我将使用
mapsync
,小心不要使用
.async
(与后者一样,至少缺少用于调度任务的自定义
Actormatarializer
或dispatcher,不会将背压传播得如此紧密)

在这种情况下,机上计数永远不会超过4(一个在第一个
mapAsync
之前(由于操作员融合),一个在第一个
mapAsync
中,一个在第二个
mapAsync
中,一个在第二个
mapAsync
之后).如果你想在特定阶段限制机上元素的数量,这是一个好办法

但是,如果您只想在流中限制正在进行的工作,那么将业务逻辑移动到单个
未来
中,并在
mapAsync
中生成数量有限的未来,您只需旋转一个旋钮:

val fut: Future[Done] = source
  .mapAsync(5) { i =>
    Future { quintuple(i) }
      .map(minusOne)
      .map(double)
  }
  .via(toUnit)
  .runWith(Sink.ignore)

您所说的是溢出策略。在第一个示例中,显示了您想要的溢出策略:
OverflowStrategy.backpressure

Akka流是反应式的,这意味着通过将溢出策略设置为背压,你告诉你所连接的制作人你现在不能消耗更多的数据。但是,只有当你上游的所有东西都能处理你不打算处理更多元素的事实时,这才有效

在您的情况下,这样的方法应该会起作用,因为我们的
源代码可以被反压:

导入scala.concurrent.duration_
隐式val system=ActorSystem()
FileIO.fromPath(path.get(…)
.via(Compression.gunzip())
.via(Framing.delimiter(ByteString(“\n”),maximumFrameLength=255))
.map(u.utf8String)
.缓冲器(10,溢流策略背压)
.节气门(元件=1,每秒钟=1)
.to(Sink.foreach(println))
.run()
在这个非常简单的例子中很容易看到背压的作用。因为我们使用
节流阀
流量将对上游产生背压,因此每秒只发出1个元素。如果输入文件足够大,这将很快填满10个元素的缓冲区

如果您切换到使用
OverflowStrategy.fail
并再次尝试运行此选项,您会发现由于缓冲区已满,流几乎立即失败:

[ERROR] [Buffer(akka://default)] Failing because buffer is full and overflowStrategy is: [Fail]


在下面的堆栈中,我们非常感谢您的辛勤工作。请提供一些代码,这些代码让您无法前进。感谢您的快速回复!我目前有以下内容:
source.via(解析)。via(组件1)。to(组件2)。run()
。在我的流的解析阶段,我不希望对通过它的元素的数量有任何限制。从组件1的入口一直到接收器,流的整个部分最多有100个元素在运行。我还可以提到,组件2是一个非常复杂的组件,具有pa广播、广播、自定义合并和多个接收器。不知道这是否会影响任何内容。您的方法适用于此描述吗?
[ERROR] [Buffer(akka://default)] Failing because buffer is full and overflowStrategy is: [Fail]