从Jenkins管道并行步骤收集数据

时间:2019-02-25 13:43:16

标签: jenkins groovy jenkins-pipeline

从并行步骤收集数据(例如通过/失败结果)的最佳方法是什么。

到目前为止我已经达到的目标:

#!groovy
def fspam(name, spam){
    spam[name] = "BEEN THERE TOO"
}

// pipeline
node('slave'){
    stage("test"){
        targets = ["a", "b"]
        def tasks = [:] 
        def spam = [:]
        targets.each{ tasks["${it}"] = {
            node('slave'){
                echo "dry-run ${it}"
                spam[it] = "BEEN THERE" <--- works
                fspam(it)         <--- fails
            } 
        } 

        }
        parallel tasks
        print("spam")
        print(spam)
    }
}

但是失败了:

  

也:groovy.lang.MissingPropertyException:无此类属性:stam   适用于类:WorkflowScript groovy.lang.MissingPropertyException:否   此类属性:stam类:WorkflowScript位于   org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:53)

  1. 似乎封闭式地成功填充了地图,但是使用函数时会引发错误
  2. 我不确定拥有全球地图是最好/最干净的方式

任何建议

2 个答案:

答案 0 :(得分:1)

好吧,错过了一个显而易见的解决方案:

#!groovy
def fspam(name, spam){
    spam[name] = "BEEN THERE TOO"
}

// pipeline
node('slave'){
    stage("test"){
        targets = ["a", "b"]
        def tasks = [:] 
        def spam = [:]
        targets.each{ tasks["${it}"] = {
            node('slave'){
                echo "dry-run ${it}"
                spam[it] = "BEEN THERE"
                fspam(it, spam)         <--- passing spam fixes the issue
            } 
        } 

        }
        parallel tasks
        print("spam")
        print(spam)
    }
}

一个问题仍然存在:有更好/更清洁的方法吗?(线程安全性/ jenkins管道本机等)

答案 1 :(得分:1)

使用.asSynchronized()

targets = ["a", "b"]

tasks = [:]
spam = [:].asSynchronized()

targets.each { target ->
    tasks[target] = {
        echo "dry-run ${target}"
        spam[target] = "BEEN THERE"
        fspam(target, spam)         // <--- passing spam fixes the issue
    } 
}

parallel tasks

print("spam")
print(spam)

这保证了对映射的更新是线程安全的。要收集列表,可以使用[].asSynchronized()Link