Run a FOR LOOP concurrently in Groovy? - multithreading

I'm trying to find options where we can run a FOR loop concurrently in Groovy? I have a Jenkins file and I would like the for loop to run in parallel there
Something like the following code. I would like that all these for loops can run in parallel. Order is not a problem. It's just that the steps inside the for loop should be completed.
vars=[*,*,*,*,*]
for i in vars:
'''steps'''

You need to use the parallel directive. This is what you can do for a for loop. You should be able to use this code and adapt it to yours
def testList = ["a", "b", "c", "d"]
def branches = [:]
for (int i = 0; i < 4 ; i++) {
int index=i, branch = i+1
branches["branch_${branch}"] = {
sh "echo 'node: ${NODE_NAME}, index: ${index}, i: ${i}, testListVal: " + testList[index] + "'"
}
}
parallel branches

Related

Declare Variables In Groovy FOR Loop

I want to create a loop in Groovy, that declares two objects. Then sets these two objects to the JSON values produced from Terraform command.
for(int i = 0; i < 2; i++) {
def "instance_" + i
"instance_" + i = terraform output -json EC2Instance_IDs | jq -r '.[0]'
println instance_ + i
}
I've been getting errors, such as:
(instance_ + i) is a binary expression, but it should be a variable expression at line:
and,
unexpected token: instance_ # line 52, column 45. def instance_
You'll need something like this:
0.upto(1) { i ->
this."instance_$i" = "Fred $i"
println this."instance_$i"
}
Running the above snippet will give this output:
Fred 0
Fred 1
Or you could use a collection.

Guidance: converting parallelly increamental nested loop to streams

I am trying to convert the following loop to Java stream.
def a = [12,34,5,64,24,56], b = [1,23,45]
for(int i=0;i<a.size();)
for(int j=0;j<b.size() && a[i];j++)
println a[i++]+","+b[j]
Output:
12,1
34,23
5,45
64,1
24,23
56,45
I tried few ways but I am not sure how to increment outer loop from inner loop. Any guidance is appreciated. The following code is the furthest I have done.
a.stream().forEach({x ->
b.stream().filter({y-> y%2 != 0}).forEach({ y->
println x+","+y
});
});
Output:
12,1
12,23
12,45
34,1
34,23
34,45
5,1
5,23
5,45
64,1
64,23
64,45
24,1
24,23
24,45
56,1
56,23
56,45
IntStream.range(0, left.length)
.mapToObj(x -> left[x] + " " + right[x % right.length])
.forEachOrdered(System.out::println);
where left is a and right is b

Groovy find the last iteration inside a cloure?

In groovy how to find the last iteration inside the closure.
def closure = { it->
//here I need to print last line only
}
new File (file).eachLine{ closure(it)}
Need to find inside the closure iteration.
Update 1:
Instead of reading a file, In Common How can i find the last iteration inside the closure ?
def closure = { it->
//Find last iteration here
}
I guess you need eachWithIndex:
def f = new File('TODO')
def lines = f.readLines().size()
def c = { l, i ->
if(i == lines - 1) {
println "last: $i $l"
}
}
f.eachWithIndex(c)
Of course in case of big files you need to count lines efficiently.

Iterate and print content of groovy closures

In a loop I create 4 closures and add them to a list:
closureList = []
for (int i=0; i<4; i++) {
def cl = {
def A=i;
}
closureList.add(cl)
}
closureList.each() {print it.call()println "";};
This results in the following output:
4
4
4
4
But I would have expected 0,1,2,3 instead. Why does the 4 closures have the same value for A?
Yeah, this catches people out, the free variable i is getting bound to the last value in the for loop, not the value at the time the closure was created.
You can either, change the loop into a closure based call:
closureList = (0..<4).collect { i ->
{ ->
def a = i
}
}
closureList.each { println it() }
Or create an extra variable that gets re-set every time round the loop, and use that:
closureList = []
for( i in (0..<4) ) {
int j = i
closureList << { ->
def a = j
}
}
closureList.each { println it() }
In both of these variants the variable closed by the closure is created afresh each time round the loop, so you get the result you'd expect

Groovy for loop with multiple counters?

Following works in groovy -
for(def i=0;i<10;i++)
print i
But this which is valid in Java, C++ does not work in groovy -
for(def i=0,j=0;i<10;i++,j++)
print i + ' ' + j
Why? How to make this work?
It will not working as Groovy does not accept multiple expressions in a for loop.
Try this:
[0..10,0..10].transpose().each{ i, j ->
println i + ' ' + j
}
to achieve the same result.
Update to make it more generalized. This update is equivalent to increment with i++, j+=3.
(0..<10).collect{[it, it+3]}.each{ i, j ->
println i + ' ' + j
}
Have you tried this:
for( def ( int i, int j ) = [ 0, 0 ]; i < 10; i++, j++ )
If that doesn't work, it might be failing because of the last part.
C++ has a explicit comma operator, which is how it allows constructs like this.
Java does not have a comma operator, but presumably allows constructs such as this as a hack to the for loop.
If Groovy wont allow this, it's most probably because it doesn't allow this hack.

Resources