【问题标题】:collect data from Jenkins pipeline parallel steps从 Jenkins 管道并行步骤收集数据
【发布时间】:2019-02-25 13:43:15
【问题描述】:

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

到目前为止我已经达到了什么:

#!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 at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:53)

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

任何建议

【问题讨论】:

    标签: jenkins groovy jenkins-pipeline


    【解决方案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

    【讨论】:

    【解决方案2】:

    好吧,错过了一个明显的解决方案:

    #!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 管道原生等)

    【讨论】: