Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Akka流滑动窗口控制减少SourceQueue向接收器发射_Java_Streaming_Akka_Akka Stream - Fatal编程技术网

Java Akka流滑动窗口控制减少SourceQueue向接收器发射

Java Akka流滑动窗口控制减少SourceQueue向接收器发射,java,streaming,akka,akka-stream,Java,Streaming,Akka,Akka Stream,更新:我提出问题是为了详细解释我的意思 ===================================================================== 我有一个Akka源代码,它可以继续从数据库表中读取数据,并通过一些键进行分组,然后对其进行缩减。然而,在我应用reduce函数之后,数据似乎永远不会发送到sink,因为上游总是有数据来,所以它将继续reduce 我读了一些帖子,并尝试了GroupedIn和Slide,但它并没有像我想的那样工作,它只将消息分组到更大的部

更新:我提出问题是为了详细解释我的意思

=====================================================================

我有一个Akka源代码,它可以继续从数据库表中读取数据,并通过一些键进行分组,然后对其进行缩减。然而,在我应用reduce函数之后,数据似乎永远不会发送到sink,因为上游总是有数据来,所以它将继续reduce

我读了一些帖子,并尝试了GroupedIn和Slide,但它并没有像我想的那样工作,它只将消息分组到更大的部分,而从不让上游暂停并发射到接收器。以下是Akka stream 2.5.2中的代码

源代码:

source = source
  .groupedWithin(100, FiniteDuration.apply(1, TimeUnit.SECONDS))
  .sliding(3, 1)
  .mapConcat(i -> i)
  .mapConcat(i -> i)
  .groupBy(2000000, i -> i.getEntityName())
  .map(i -> new Pair<>(i.getEntityName(), i))
  .reduce((l, r) ->{ l.second().setAction(r.second().getAction() + l.second().getAction()); return l;})
  .map(i -> i.second())
  .mergeSubstreams();
我现在所做的代码如下

("table1" 1+4),("table3", 3+5),("table2", 2)
source
.groupBy(2000000, systemCodeTracking -> systemCodeTracking.getEntityName)
.map(systemCodeTracking -> new Pair<String, Integer>(systemCodeTracking.getEntityName, SystemCodeTracking.getId()))
.scan(....)
源代码
.groupBy(2000000,systemCodeTracking->systemCodeTracking.getEntityName)
.map(systemCodeTracking->新对(systemCodeTracking.getEntityName,systemCodeTracking.getId())
.扫描(…)
我现在的问题更多的是关于如何构建扫描初始状态 我该怎么办

scan(new Pair<>("", 0), (first, second) -> first.setId(first.getId() + second.getId()))
scan(新对(“,0),(第一,第二)->first.setId(first.getId()+second.getId())

如果我对每件事都很了解,那么你想要的是:

  • 首先,按id分组
  • 然后按时间窗口分组,在此时间窗口内,对所有
    systemCodeTracking.getId()进行求和
对于第一部分,您需要
groupBy
。对于第二部分
groupedWithin
。但是,它们的工作原理不同:第一个将为您提供子流,而第二个将为您提供列表流

因此,我们必须以不同的方式处理这些问题

首先,让我们为列表编写一个减速机:

private SystemCodeTracking reduceList(List<SystemCodeTracking> list) throws Exception {
    if (list.isEmpty()) {
        throw new Exception();
    } else {
        SystemCodeTracking building = list.get(0);
        building.setId(0L);
        list.forEach(next -> building.setId(building.getId() + next.getId()));
        return building;
    }
}

所以,如果我对每件事都很了解,你想要的是:

  • 首先,按id分组
  • 然后按时间窗口分组,在此时间窗口内,对所有
    systemCodeTracking.getId()进行求和
对于第一部分,您需要
groupBy
。对于第二部分
groupedWithin
。但是,它们的工作原理不同:第一个将为您提供子流,而第二个将为您提供列表流

因此,我们必须以不同的方式处理这些问题

首先,让我们为列表编写一个减速机:

private SystemCodeTracking reduceList(List<SystemCodeTracking> list) throws Exception {
    if (list.isEmpty()) {
        throw new Exception();
    } else {
        SystemCodeTracking building = list.get(0);
        building.setId(0L);
        list.forEach(next -> building.setId(building.getId() + next.getId()));
        return building;
    }
}

为什么要在分组流之后放置
mapConcat
?因为GroupedIn和sliding会给我一个对象列表,但我只需要逐个减少它。我应该减少整个列表吗?是的。您应该使用其中一种(滑动或GroupedIn),然后减少每个列表元素。我相信你真正想要的是GroupedIn,这正是一个时间窗口(最大大小)。@Cyrille你能告诉我怎么做吗?因为一旦我使用GroupedIn,它将返回我的列表,如果我不执行mapCancat,我就不能应用reduce函数。为什么在分组流之后放置
mapConcat
?因为GroupedIn和Slide将给我一个对象列表,但我只需要逐个减少它。我应该减少整个列表吗?是的。您应该使用其中一种(滑动或GroupedIn),然后减少每个列表元素。我相信你真正想要的是GroupedIn,这正是一个时间窗口(最大大小)。@Cyrille你能告诉我怎么做吗?因为一旦我使用GroupedIn,它将返回我的列表,如果我不使用mapCancat,我就不能应用reduce函数。再一次,对java风格感到抱歉,我真的更习惯scala代码。@Cynille非常感谢你的回答,它工作得很好。我以更java的风格对GroupedIn做了一点修改;-)。请接受它,我也会接受这个答案。。唯一的问题是,我想我似乎无法使用本机的reduce函数来实现这一点。但无论如何,再次感谢你@愤世嫉俗者为什么拒绝。groupedWithin(100,秒)在java中并不复杂,应该是这样。我想groupedWithin(100,FiniteDuration.create(10,TimeUnit.SECONDS))应该是这样。对不起。以前我认为在变量中定义我的窗口是可以的(而且更干净)。我无法取消拒绝编辑:-(再次对java风格表示抱歉,我确实更习惯scala代码。@Cysille非常感谢您的回答,它工作得很好。我以更java风格对GroupedIn进行了一些修复;-)。请接受它,我也会接受这个答案。。唯一的问题是,我想我似乎无法使用本机的reduce函数来实现这一点。但无论如何,再次感谢你@愤世嫉俗者为什么拒绝。groupedWithin(100,秒)在java中并不复杂,应该是这样。我想groupedWithin(100,FiniteDuration.create(10,TimeUnit.SECONDS))应该是这样。对不起。以前我认为在变量中定义我的窗口是可以的(而且更干净)。我无法取消拒绝编辑:-(
Source<SystemCodeTracking, SourceQueueWithComplete<SystemCodeTracking>> loggedSource = source
    .groupBy(20000, SystemCodeTracking::getEntityName) // group by name
    .groupedWithin(100, FiniteDuration.create(10, TimeUnit.SECONDS)   // for a given name, group by time window (or by packs of 100)
    .filterNot(List::isEmpty)                          // remove empty elements from the flow (if no element has passed in the last second, to avoid error in reducer)
    .map(this::reduceList)                             // reduce each list to sum the ids
    .log("====== doing reduceing ")                    // log each passing element using akka logger, rather than `System.out.println`
    .mergeSubstreams()                                 // merge back all elements with different names