与工作流程插件同时多次启动一项工作 [英] Start a job multiple times concurrently with workflow plugin

查看:100
本文介绍了与工作流程插件同时多次启动一项工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用工作流程插件同时运行一个作业5次。这里是代码片段:

  def concurrent = [:] 
for(int i = 0; i <5 ; i ++){
concurrent [concurrent $ {i}] = {
build job:'test_job',parameters:[[$ class:'StringParameterValue',name:'queue',value:
'automation_prod.q'],[$ class:'StringParameterValue',name:'dummy',value:$ {i}]]
}
}
并行并发

这段代码会导致test_job只运行一次。
我需要它同时运行5次。



谢谢!

解决方案

除了缺少对脚本错误的诊断之外,Workflow中没有任何错误。在Groovy中,循环计数器 i 在封闭范围中定义并发生变化,因此在每个闭包运行时,它具有相同的值:5.您可以看到这一点,以及Jenkins之外的修复背后的概念:

$ groovy -e'def cs = []; for(int i = 0; i <5; i ++){def j = i; cs + = {println$ {i} vs. $ {j}}}; for(c in cs){c()}'
5对0
5对1
5对2
5对3
5 vs 。4

在你的情况下,Jenkins看到五次尝试用相同的参数来调度同一个下游项目,并将它们全部合并为一个队列项目,从而构建一个队列项目。 (根据时间的推移,它可能在其他 build 步骤甚至运行之前开始了一个下游构建,在这种情况下,它将运行第二个下游构建,但通常它会少于)



这个新测试表明你想要做的事情确实是可能的;你只需要在闭包之外的一个新的词汇范围变量中捕获循环变量的 current 值。

顺便说一下
p>

  def cs = []; (0..4).each {i  - > cs + = {println i}}; cs * .call()

按照预期从命令行Groovy工作,因为没有突变循环变量。不幸的是,这种语法在工作流程中尚不可用: JENKINS-26481



请注意,您应不要使用虚拟参数值来区分队列条目。尽管今天可​​能会发生这种情况,但希望该行为能够得到解决,以便由 build 指定的参数值与下游项目中实际定义的任何参数不相符被警告跳过或导致错误。如果你认为你需要一个虚拟参数,那么你可能会做其他的事情,但是你可能会做一些其他的错误,但是没有任何解释说明你为什么希望一个下游项目运行多次,而没有任何东西可以区分这些构建。

I am trying to run one job 5 times concurrently using the workflow plugin. here is the snippet:

def concurrent=[:]
for (int i = 0; i < 5; i++) {
concurrent["concurrent${i}"] = {
build job: 'test_job', parameters: [[$class: 'StringParameterValue', name:'queue', value:     
'automation_prod.q'],[$class: 'StringParameterValue', name:'dummy', value: "${i}"]]
    }
}
parallel concurrent

this snippet causes the the test_job to run only once. I need it running 5 times concurrently.

thanks!

解决方案

There is no bug in Workflow here beyond a lack of diagnosis for the mistake in the script. In Groovy, the loop counter i is defined in an enclosing scope and mutated, so by the time each closure runs, it has the same value: 5. You can see this, as well as the concept behind the fix, outside Jenkins:

$ groovy -e 'def cs = []; for (int i = 0; i < 5; i++) {def j = i; cs += {println "${i} vs. ${j}"}}; for (c in cs) {c()}'
5 vs. 0
5 vs. 1
5 vs. 2
5 vs. 3
5 vs. 4

In your case, Jenkins saw five attempts to schedule the same downstream project with the same parameters, and coalesced them all into one queue item and thus one build. (Depending on timing, it might have started one downstream build before other build steps even ran, in which case it would run a second downstream build, but generally it would be fewer than five total builds.)

This new test demonstrates that what you wanted to do is indeed possible; you just need to capture the current value of the loop variable in a new lexically-scoped variable outside the closure.

By the way

def cs = []; (0..4).each {i -> cs += {println i}}; cs*.call()

does work as expected from command-line Groovy, since there is no mutated loop variable. Unfortunately this syntax is not yet available in Workflow: JENKINS-26481

Beware that you should not be using a "dummy" parameter value to differentiate queue entries. While this may happen to work today, expect that behavior to be fixed, so that parameter values specified by build which do not correspond to any parameter actually defined in the downstream project will either be skipped with a warning, or result in an error. If you think you need a dummy parameter, you are probably doing something else wrong, but it is impossible to advise what that is without any explanation of why you would want a downstream project to run multiple times with nothing in its input differentiating the builds.

这篇关于与工作流程插件同时多次启动一项工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆