首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用声明式管道执行并行阶段,仅使用列表中的最后一项

使用声明式管道执行并行阶段,仅使用列表中的最后一项
EN

Stack Overflow用户
提问于 2018-03-23 12:33:55
回答 1查看 1K关注 0票数 1

我不知道我在这里做错了什么,因为目前当我试图迭代列表时,创建阶段似乎很好,但是在执行seems脚本时,所使用的值始终是列表的最后一项:

工作管道:

代码语言:javascript
复制
pipeline {
    agent any
    stages {
        stage('set servers') {
            steps {
                script {
                    my_list = ['server1','server-2','server-3']
                }
            }
        }
        stage('Execute then') {
            parallel {
                stage('shouter') {
                    steps {            
                        script {
                            shouter = [:]
                            script {
                                for(i in my_list) {
                                    shouter["${i}"] = {
                                        echo "standupandshout.sh ${i}"
                                    }
                                }
                            }                            
                            parallel shouter
                        }
                    }
                }
            }
        }
    }
}

输出:

控制台输出:

代码语言:javascript
复制
Replayed #4
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/test
[Pipeline] {
[Pipeline] stage
[Pipeline] { (set servers)
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Execute then)
[Pipeline] parallel
[Pipeline] [shouter] { (Branch: shouter)
[Pipeline] [shouter] stage
[Pipeline] [shouter] { (shouter)
[Pipeline] [shouter] script
[Pipeline] [shouter] {
[Pipeline] [shouter] script
[Pipeline] [shouter] {
[Pipeline] [shouter] }
[Pipeline] [shouter] // script
[Pipeline] [shouter] parallel
[Pipeline] [server1] { (Branch: server1)
[Pipeline] [server-2] { (Branch: server-2)
[Pipeline] [server-3] { (Branch: server-3)
[Pipeline] [server1] echo
[server1] standupandshout.sh server-3
[Pipeline] [server1] }
[Pipeline] [server-2] echo
[server-2] standupandshout.sh server-3
[Pipeline] [server-2] }
[Pipeline] [server-3] echo
[server-3] standupandshout.sh server-3
[Pipeline] [server-3] }
[Pipeline] [shouter] // parallel
[Pipeline] [shouter] }
[Pipeline] [shouter] // script
[Pipeline] [shouter] }
[Pipeline] [shouter] // stage
[Pipeline] [shouter] }
[Pipeline] // parallel
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

期望输出:

代码语言:javascript
复制
[Pipeline] [server1] echo
[server1] standupandshout.sh server-1
[Pipeline] [server1] }
[Pipeline] [server-2] echo
[server-2] standupandshout.sh server-2
[Pipeline] [server-2] }
[Pipeline] [server-3] echo
[server-3] standupandshout.sh server-3
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-27 08:54:25

这是由groovy闭包造成的,当它们包含的代码被计算时。http://blog.freeside.co/2013/03/29/groovy-gotcha-for-loops-and-closure-scope/

当运行闭包时,绑定到变量i的值是它在循环的最后一次迭代中的值,而不是创建闭包的迭代。闭包的作用域具有对i的引用,在执行任何闭包时,I都是5。 循环体局部变量的行为显然不是这样的,因为每个闭包作用域都包含对不同变量的引用。

这就是为什么你的艺名是好的,但你的价值不是。

解决办法是什么?我们应该总是使用.each而不是for循环吗?嗯,在很多情况下,我有点喜欢for循环,并且可能存在内存利用率的差异(不要认为循环“更好”或“更有效”)。 如果您简单地将循环变量化名并在闭包体中引用该别名,那么所有这些都会很好。

代码语言:javascript
复制
def fns = []
for (i in (1..5)) {
    def myi = i
    def isq = i * i
    fns << {->
        println "$myi squared is $isq"
    }
}
fns.each { it() }

所以这应该是可行的:

代码语言:javascript
复制
script {
  shouter = [:]
  for(i in my_list) {
    def val = i
    shouter["${i}"] = {
      echo "standupandshout.sh ${val}"
    }
  }
  parallel shouter
}                            
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49449785

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档