Currying groovy CPS closure for parallel execution

瘦欲@ 提交于 2019-11-29 13:27:23

I'm not sure if it's the currying, or the for loop, but this function needs to be marked as NonCPS as described here: https://github.com/jenkinsci/pipeline-examples/blob/master/docs/BEST_PRACTICES.md#groovy-gotchas

Essentially, do this:

@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
}

I think it's your for loop, but regardless, anytime you don't use classic "C Style" loops, you'll need to mark your function as NonCPS.

This seems to be a limitation of either the Groovy language or the Jenkins groovy runtime, I'm not sure which, but it's worth noting their examples do exactly as you have done, declaring a new variable for each iteration of the loop.

They have commented their example

// fresh variable per iteration; i will be mutated

I don't think that using C-style loops will remove this limitation and currying (which would be required for this use case) does not resolve the issue either. Clumsy, but easy enough to work around.

https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md#creating-multiple-threads

Found that with the latest Pipeline: Groovy plugin (2.40) combined with at least Jenkins Version 2.60.3 (works although the plug-ins homepage states that you need at least Jenkins 2.73.3) everything works as expected.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!