Dynamic closures called in parallel

23 views
Skip to first unread message

Mirek S

unread,
Aug 9, 2017, 11:17:53 AM8/9/17
to Jenkins Users
Hi!

I'm using the following Pipeline script:

testruns = [:]
for (name in ["one", "two", "three"]) {
  print("Adding ${name} to testruns")
  testruns[name] = { print("Staring phase ${name}"); sleep 10; print("Finished phase ${name}")}
}

pipeline {
  agent { label 'master' }
  stages {
    stage("Parallelism") {
      steps {
        script {
          parallel testruns
        }
      }
    }
  }
}

I'm expecting to run those three dynamically created closures in parallel. But it appears that all closures were created using only the last field ("three"). Console output:

Started by user ...
[Pipeline] echo
Adding one to testruns
[Pipeline] echo
Adding two to testruns
[Pipeline] echo
Adding three to testruns
[Pipeline] node
Running on master in ...
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Parallelism)
[Pipeline] script
[Pipeline] {
[Pipeline] parallel
[Pipeline] [one] { (Branch: one)
[Pipeline] [two] { (Branch: two)
[Pipeline] [three] { (Branch: three)
[Pipeline] [one] echo
[one] Staring phase three
[Pipeline] [one] sleep
[one] Sleeping for 10 sec
[Pipeline] [two] echo
[two] Staring phase three
[Pipeline] [two] sleep
[two] Sleeping for 10 sec
[Pipeline] [three] echo
[three] Staring phase three
[Pipeline] [three] sleep
[three] Sleeping for 10 sec
[Pipeline] [one] echo
[one] Finished phase three
[Pipeline] [one] }
[Pipeline] [two] echo
[two] Finished phase three
[Pipeline] [two] }
[Pipeline] [three] echo
[three] Finished phase three
[Pipeline] [three] }
[Pipeline] // parallel
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS


Please note that all phases are saying "three":

[two] Finished phase three

I was thinking that maybe there's a need for some kind of splat operator on argument for "parallel", but pipeline parallel example doesn't use it (and when I tried I got java.lang.UnsupportedOperationException)

What am I not seeing here? Why the closures are not created properly?

Mirek S

unread,
Aug 9, 2017, 11:27:40 AM8/9/17
to Jenkins Users
Huh... Only now I noticed that my issue is mentioned in the pipeline parallel example. You can ignore this topic :)

//the dummy parameter is for preventing mutation of the parameter before the execution of the closure.
//we have to assign it outside the closure or it will run the job multiple times with the same parameter "4"
//and jenkins will unite them into a single run of the job

Björn Pedersen

unread,
Aug 9, 2017, 11:28:03 AM8/9/17
to Jenkins Users

Hi,

your problem is  actually addressed in the example.
The closure is evalutated only during the parallel call. There $name is constant.
Put a
def xname  = name
inside your loop and use xname in the closures.
 (in the example it is  the def index=i line).

Björn
Reply all
Reply to author
Forward
0 new messages