Start a job multiple times concurrently with workf

2019-01-23 00:15发布

问题:

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!

回答1:

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.