Groovy gpars数据流队列处理或管道似乎仅在df.val请求时触发

Groovy gpars数据流队列处理或管道似乎仅在df.val请求时触发,groovy,gpars,dataflowtask,Groovy,Gpars,Dataflowtask,我需要一些帮助。查看GPAR数据流/管道,但我不明白 如果你看下面的例子,我已经用操作符、管线、链接和命中同一个问题完成了这项工作 在本例中,我使用了任务,但也可以不使用相同的问题清单。在本例中,我设置了两个DataFlowQueue,一个用于初始条件,另一个用于根据谓词求值的结果。然后,我布局了一个管道,该管道根据谓词is-event测试的输入来评估输入,并将结果存储在输出结果队列中 在设置管道并将一些条目发布到第一个队列之后,我相信条目会在数据可用时进行处理。这对于操作员版本也不起作用,因为

我需要一些帮助。查看GPAR数据流/管道,但我不明白

如果你看下面的例子,我已经用操作符、管线、链接和命中同一个问题完成了这项工作

在本例中,我使用了任务,但也可以不使用相同的问题清单。在本例中,我设置了两个DataFlowQueue,一个用于初始条件,另一个用于根据谓词求值的结果。然后,我布局了一个管道,该管道根据谓词is-event测试的输入来评估输入,并将结果存储在输出结果队列中

在设置管道并将一些条目发布到第一个队列之后,我相信条目会在数据可用时进行处理。这对于操作员版本也不起作用,因为您可以看到,如果我删除了任务,那么结果的大小将为零。在我将条目写入sessionQ之后,该任务仍然为真。因此,写入数据不会“触发”处理

第一个任务将大量条目保存到队列中

import groovyx.gpars.dataflow.Dataflow
import groovyx.gpars.dataflow.DataflowQueue
import groovyx.gpars.dataflow.DataflowVariable
import groovyx.gpars.dataflow.Promise

/**
 * Created by will on 13/01/2017.
 */

def iValues = [1,2,3,4,5]

DataflowQueue sessionQ = new DataflowQueue()
DataflowQueue resultQ = new DataflowQueue()

Dataflow.task {
    println "setup task: set initial conditions list for rule predicate "
    iValues.each {sessionQ << it}
}

Closure evenPredicate = {it %2 == 0}

//layout pipeline 
sessionQ | evenPredicate   | resultQ

assert resultQ.iterator().size() == 0

Promise ans =  Dataflow.task {
    println "result task : get three values from result q "
    def outlist = []
    3.times {
        def res = resultQ.val
        println "got result $res"
        outlist << res
    }
    assert sessionQ.iterator().size() == 0
    assert resultQ.iterator().size() == 2
    outlist
}

println "ans list is $ans.val"
assert resultQ.iterator().size() == 2
因为它总是空的,直到您使用sessionQ中的第一项。我不明白为什么?在条目被绑定到第一个dataflowQueue之后,我原以为这些条目在可用时会被使用,但它们并没有被绑定

这是一个棘手的问题,因为在读取sessionQ的第一个DF之前,您无法通过resultQ获取条目、检查结果大小、进行投票,因为它将失败

最后,我不得不使用初始值数组的大小来告诉我保存到队列中的条目,作为从resultQ中读取相同数字以清空它的唯一方法。在上面的例子中,我只消耗了resultsQ中的3条记录,断言显示resultQ中仍有2条记录,但仅在这之后首先进行.val调用,如果您注释该行,则所有断言都将开始失败

我用Dataflow.operator、Pipeline等试过了,也遇到了同样的问题。为什么当每个输入都绑定到SessionQ时,工作没有得到处理

最后,对于管道,有一个.complete方法,如果您在管道中处理一个闭包{},它将保持打开状态!完成,但当您运行.binaryChoice之类的方法时,它会将管道标记为已完成,无法添加进一步的操作。为什么要这样做

我不明白那个状态在说什么,当然不会再进行处理,如果您尝试在这样一个方法之后执行另一个步骤,就会抛出异常

不管怎样,我试过这样的管线

Pipeline pipeLine = new Pipeline(Q)
pipeLine.tap(log).binaryChoice(evenPathQ, oddPathQ) {println "$it %2 is ${it%2 ==0}"; (it%2 == 0) }
然而,当您将值绑定到Q时,什么也不会发生——直到您使用类似于

odd.val
当管道突然“运行”并处理Q中存储的所有DF项时

除了第一次.val消费之外,我尝试过的任何东西都不能启动工作的日程安排

可以解释为什么会这样,我必须忽略这里的要点,但是在读取第一个条目之前“什么也不做”并不是我所期望的,它会使任何大小评估无效。对DataflowWriteChannel目标的iterator.size、poll等类型调用

我非常感谢在这方面的任何帮助——我已经为此奋斗了两天,但一事无成。我也查看了所有GPAR测试,它们调用.val的次数与输入绑定的次数相同,所以不要显示我描述的问题

Vaclav Pech,或任何其他关注这些问题的GPAR大师,我将非常感谢任何关于这方面的帮助,以帮助我克服这一困难


提前考虑

在断言大小为0之前添加延迟的小修改将显示由写入数据触发的计算:

//layout pipeline
sessionQ | evenPredicate   | resultQ
sleep 5000
assert resultQ.iterator().size() == 0

谢谢瓦茨拉夫,我明天早上会坐火车,也许是时候让房地产“赶上”了,我的问题就解决了。我已经尝试了几次攻击,看起来工作并没有按预期进行——报告我尝试过的各种“尝试”模式的发现,看看是否真的如此。tricki添加了500毫秒的睡眠间隔,然后示例开始看起来正确,其他线程中的工作有机会在后台完成这些工作。我仍然不确定管道上的“完整”状态是什么,尽管完整状态限制管道生成器只允许建造有效的管道。当您不能再向管道附加运算符时,管道被视为已完成。例如,通过调用binaryChoice,两个通道连接到管道的末端,所有进一步的管道操作必须附加到这些通道中的任何一个,而不是原始管道。好的,谢谢vaclav-我将返回文档并查找终止选项
//layout pipeline
sessionQ | evenPredicate   | resultQ
sleep 5000
assert resultQ.iterator().size() == 0