groovy 将failFast与闭包Map结合使用,可以打破“并行”步骤

bq9c1y66  于 6个月前  发布在  其他
关注(0)|答案(4)|浏览(78)

不知道是我对Groovy的知识有限还是Pipeline parallel步骤中的一个怪癖。如果我使用map而不是单独传递每个闭包,我就不能让它接受failFast

def map = [:]
map['spam'] = {
    node {
        echo 'spam'
    }
}
map['eggs'] = {
    node {
        echo 'eggs'
    }
}
parallel map // Works.
parallel spam: map['spam'], eggs: map['eggs'], failFast: true // Works.
parallel map, failFast: true // Fails with exception.

字符串
failFast的例外是:

java.lang.IllegalArgumentException: Expected named arguments but got [{failFast=true}, {spam=org.jenkinsci.plugins.workflow.cps.CpsClosure2@51a382ad, eggs=org.jenkinsci.plugins.workflow.cps.CpsClosure2@718cb50d}]
    at org.jenkinsci.plugins.workflow.cps.DSL.parseArgs(DSL.java:276)
    at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:111)

ogsagwnx

ogsagwnx1#

map.failFast = true
parallel map

字符串

gdx19jrr

gdx19jrr2#

如果你添加可选的语法,它会有一点帮助。第二个选项是传递一个新的Map,而第三个选项是传递你原来的Map和一个额外的命名参数。老实说,我不知道它是怎么想的。

parallel(map)
parallel([
    spam: map['spam'],
    eggs: map['eggs'],
    failFast: true
])
parallel map, failFast: true

字符串
无论如何,我认为最简单的事情是这样的:

def map = [
    spam: {
        node {
            echo 'spam'
        }
    },
    eggs: {
        node {
            echo 'eggs'
        }
    },
    failFast: true
]
parallel map


或者...

parallel ([
    spam: {
        node {
            echo 'spam'
        }
    },
    eggs: {
        node {
            echo 'eggs'
        }
    },
    failFast: true
])

drnojrws

drnojrws3#

Jesse Glick的answer
即使你使用for循环来创建一个并行stages,你也可以使用相同的代码-

map.failFast = true
parallel map

字符串

aydmsdu9

aydmsdu94#

所有的答案都提供了解决方案,但没有一个解释你得到异常的原因。
要理解这一点,阅读Groovy的命名参数是有益的。
在Groovy中,要创建一个可以接受命名参数的函数,必须将其声明为接受单个Map参数的函数。示例:

void copy(Map params) {
    println params.src
    println params.dest
}
// The next two lines are equivalent:
copy([ src: '/etc/config', dest: '/home/john' ])
copy src: '/etc/config', dest: '/home/john'

字符串
然而,这是错误的:

final map = [ src: '/etc/config' ]
// The next two lines are equivalent, and will throw an exception:
copy(map, [ dest: '/home/john' ])
copy map, dest: '/home/john'


所以你试图调用一个需要一个map的函数,但是你传递给它两个map。
要亲自查看,请尝试在本地执行此测试Groovy代码,不需要Jenkins

def printArgs(...args) {
    println args.length
    println args.collect{ it.toString() }.join(', ')
}
            
def map = [ spam: 10, eggs: 20 ]
printArgs map // Single map
printArgs spam: map['spam'], eggs: map['eggs'], failFast: true // Single map
printArgs map, failFast: true // Two maps


最后,有几个替代解决方案可以在不修改原始map的情况下工作:

// The next two lines are equivalent:
parallel map + [ failFast: true ]
parallel map.plus(failFast: true)

相关问题