Java 如何使用akka流在图中限制请求? 出身背景

Java 如何使用akka流在图中限制请求? 出身背景,java,akka,buffer,akka-stream,Java,Akka,Buffer,Akka Stream,我有一个项目,我们正在使用akka streams和Java 在这个项目中,我有一个字符串流和一个对它们进行一些操作的图形 客观的 在我的图表中,我想将该流广播给2个工人。其中一个将用“a”替换所有字符“a”,并在实时接收数据时发送数据 另一个将接收数据,每3个字符串,它将连接这3个字符串并将它们映射到数字 它将如下所示: 显然,接收器2接收信息的速度不如接收器1快。但这是预期的行为。这里有趣的部分是worker 2 问题 做工人1很容易,但不难。这里的问题是做工人2。我知道akka有最多可以保

我有一个项目,我们正在使用akka streams和Java

在这个项目中,我有一个字符串流和一个对它们进行一些操作的图形

客观的 在我的图表中,我想将该流广播给2个工人。其中一个将用“a”替换所有字符“a”,并在实时接收数据时发送数据

另一个将接收数据,每3个字符串,它将连接这3个字符串并将它们映射到数字

它将如下所示:

显然,接收器2接收信息的速度不如接收器1快。但这是预期的行为。这里有趣的部分是worker 2

问题 做工人1很容易,但不难。这里的问题是做工人2。我知道akka有最多可以保存X条消息的缓冲区,但看起来我不得不选择一条现有的缓冲区,这通常会导致我选择要删除哪条消息,或者我是否希望流保持活动状态

我只想在worke2中的缓冲区达到缓冲区的最大大小时,对它拥有的所有消息执行concat和map操作,然后在重置缓冲区后发送它们

但是,即使在阅读了akka的文档之后,我也找不到一种方法,至少是使用Java

研究 我还检查了一个类似的SO问题,但是已经一年多了,没有人回答

问题 使用图形DSL,我将如何从以下位置创建路径:

源->广播->工作者2->接收器2

在bcast之后,应用groupedWithin操作符,持续时间不限,元素数设置为3。

您也可以自己做,添加一个阶段,将元素存储在列表中,并在每次到达3个元素时发出列表

import akka.stream.Attributes;
import akka.stream.FlowShape;
import akka.stream.Inlet;
import akka.stream.Outlet;
import akka.stream.stage.AbstractInHandler;
import akka.stream.stage.GraphStage;
import akka.stream.stage.GraphStageLogic;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;

public class RecordGrouper<T> extends GraphStage<FlowShape<T, List<T>>> {

  private final Inlet<T> inlet = Inlet.create("in");
  private final Outlet<List<T>> outlet = Outlet.create("out");
  private final FlowShape<T, List<T>> shape = new FlowShape<>(inlet, outlet);

  @Override
  public GraphStageLogic createLogic(Attributes inheritedAttributes) {
    return new GraphStageLogic(shape) {
      List<T> batch = new ArrayList<>(3);

      {
        setHandler(
            inlet,
            new AbstractInHandler() {
              @Override
              public void onPush() {
                T record = grab(inlet);
                batch.add(record);
                if (batch.size() == 3) {
                  emit(outlet, ImmutableList.copyOf(batch));
                  batch.clear();
                }
                pull(inlet);
              }
            });
      }

      @Override
      public void preStart() {
        pull(inlet);
      }
    };
  }

  @Override
  public FlowShape<T, List<T>> shape() {
    return shape;
  }
}

作为一个侧节点,我不认为buffer操作符会工作,因为它只在有背压的情况下启动。因此,如果一切都是安静的,元素仍然会一个接一个地发射,而不是3个接3个

你能举一个列表法的例子吗?我对它很好奇@Flame_Phoenix,我添加了一个示例,但我还没有测试它。