为常规执行调整groovy CPS闭包

Joe*_*g S 9 parallel-processing closures currying jenkins jenkins-pipeline

我们在一些工作中动态创建并行步骤.感谢这个线程,我找到了如何动态创建带有参数的地图,以便在并行步骤中使用.

但是现在我想重用用于创建这些并行步骤的代码部分.为此,我觉得我需要为闭合咖喱做准备.

然而,currying似乎无法正常工作.在闭包内引用循环变量(valueCopy)做了正确的事情(如这里所提到的)但是currying并没有达到我的预期.

我做错了什么,这是不是(还)支持,是否有任何解决方法?这可能是Jenkins管道中的一个错误吗?

希望任何人都知道为什么这不起作用和/或如何让它工作.

Jenkins:LTS(2.32.1)及最新的插件更新截至2017/01/19.

解:

升级到Pipeline后:Groovy插件版本2.40 eveything正在按预期工作.

管道脚本执行:

def echoSome(val) {
    echo val
}

def buildClosures() {
    def someList = ["1", "2", "3"]
    def closures = [:]
    for (value in someList) {
        final valueCopy = value

        closures[value] = {val ->
                echo valueCopy.toString()
                echo val.toString()
            }.curry(value)
    }
    closures
}

parallel buildClosures()
Run Code Online (Sandbox Code Playgroud)

输出:

[Pipeline] parallel
[Pipeline] [1] { (Branch: 1)
[Pipeline] [2] { (Branch: 2)
[Pipeline] [3] { (Branch: 3)
[Pipeline] [1] echo
[1] 1
[Pipeline] [1] echo
[1] 3
[Pipeline] [1] }
[Pipeline] [2] echo
[2] 2
[Pipeline] [2] echo
[2] 3
[Pipeline] [2] }
[Pipeline] [3] echo
[3] 3
[Pipeline] [3] echo
[3] 3
[Pipeline] [3] }
[Pipeline] // parallel
[Pipeline] End of Pipeline
Finished: SUCCESS
Run Code Online (Sandbox Code Playgroud)

预期产出:

[Pipeline] parallel
[Pipeline] [1] { (Branch: 1)
[Pipeline] [2] { (Branch: 2)
[Pipeline] [3] { (Branch: 3)
[Pipeline] [1] echo
[1] 1
[Pipeline] [1] echo
[1] 1
[Pipeline] [1] }
[Pipeline] [2] echo
[2] 2
[Pipeline] [2] echo
[2] 2
[Pipeline] [2] }
[Pipeline] [3] echo
[3] 3
[Pipeline] [3] echo
[3] 3
[Pipeline] [3] }
[Pipeline] // parallel
[Pipeline] End of Pipeline
Finished: SUCCESS
Run Code Online (Sandbox Code Playgroud)

Spe*_*one 5

我不确定它是柯里化还是 for 循环,但是这个函数需要被标记为 NonCPS,如下所述: https //github.com/jenkinsci/pipeline-examples/blob/master/docs/BEST_PRACTICES。 md#groovy 陷阱

基本上,这样做:

@NonCPS
def buildClosures() {
    def someList = ["1", "2", "3"]
    def closures = [:]
    for (value in someList) {
        final valueCopy = value

        closures[value] = {val ->
                echo valueCopy.toString()
                echo val.toString()
            }.curry(value)
    }
    closures
}
Run Code Online (Sandbox Code Playgroud)

我认为这是您的 for 循环,但无论如何,无论何时您不使用经典的“C 风格”循环,您都需要将您的函数标记为 NonCPS。


Joe*_*g S 0

发现使用最新的Pipeline: Groovy插件 (2.40) 与至少 Jenkins 版本 2.60.3 相结合(尽管插件主页声明您至少需要 Jenkins 2.73.3,但可以工作),一切都按预期工作。