From 8f0b1b7c01ad8cd3325a791766884fa57d8acf73 Mon Sep 17 00:00:00 2001 From: Craig Ringer Date: Wed, 7 Nov 2018 21:39:16 +0800 Subject: [PATCH 1/2] Document error handling in the 'parallel' step --- .../workflow/cps/steps/ParallelStep/help.html | 77 ++++++++++++++++--- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/help.html b/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/help.html index e60d16906..0ea5757b3 100644 --- a/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/help.html +++ b/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/help.html @@ -1,14 +1,69 @@

- Takes a map from branch names to closures and an optional argument failFast - which will terminate all branches upon a failure in any other branch: -

-
-    parallel firstBranch: {
-        // do something
-    }, secondBranch: {
-        // do something else
-    },
-    failFast: true|false
-    
+ Takes a map from branch names to closures and runs the closures in + parallel. The optional failFast option terminates + all jobs as soon as any job fails. +

+

+ Synopsis: +

+        parallel firstBranch: {
+            // do something
+          }, secondBranch: {
+            // do something else
+          },
+          failFast: true|false
+      
+

+

+ A branch succeeds if it returns normally. The actual value + returned does not matter. A branch is considered to have failed if its + closure exits by throwing an exception. +

+

+ If any branch fails, the parallel step will throw that + exception once all branches have finished executing or been terminated, + depending on failFast mode. Any non-identical exceptions + thrown by other branches are added to the first exception as having been + "suppressed by" the first exception; see + Throwable.addSuppresssed(...). +

+

+ Note that a hudson.AbortException, as thrown by failing + steps, will stop and fail the branch but not produce a stack trace. + This produces a: +

+      [branchname] Failed in branch branchname
+      
+ message without any details. +

+

+ To report results from branches to the outer script, use the closure's + access to the outer scope's variables. For example, to run a shell script + in parallel on each of a list of arguments and produce a map of argument + to script stdout: +

+        def args = ['foo', 'bar', 'baz']
+        def results = [:]
+        // Produce a map of args to closures that use each arg
+        branches = args.collectEntries { arg -> [(arg): {
+            def out = sh script: "./my-script.sh '${arg}'", returnStdout: true
+            results << [(arg): out]
+            return null
+          } ] }
+        branches << [failFast: true]
+        parallel branches
+      
+ If all the scripts returned 0, the 'results' array contains a map of arg + to shell stdout string. Otherwise parallel terminates the + other branches and re-throws the hudson.AbortException from + the first failed script. +

+

+ Note: Branch closures should just return null. The return + value of the parallel step should be ignored. + parallel does capture the return values of closures and + return a map of branch name to return value. But relying on this is not + recommended and the behaviour is subject to change; See JENKINS-26033. +

From 2a6af3e6ce66df92d6bf43caf494bc1fc9c01266 Mon Sep 17 00:00:00 2001 From: Liam Newman Date: Wed, 9 Sep 2020 11:42:18 -0700 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Jesse Glick Co-authored-by: Devin Nusbaum --- .../workflow/cps/steps/ParallelStep/help.html | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/help.html b/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/help.html index 0ea5757b3..48522a71e 100644 --- a/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/help.html +++ b/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/help.html @@ -1,8 +1,8 @@

Takes a map from branch names to closures and runs the closures in - parallel. The optional failFast option terminates - all jobs as soon as any job fails. + parallel. The failFast option terminates + all branches as soon as any branch fails.

Synopsis: @@ -12,7 +12,7 @@ }, secondBranch: { // do something else }, - failFast: true|false + failFast: true

@@ -25,12 +25,13 @@ exception once all branches have finished executing or been terminated, depending on failFast mode. Any non-identical exceptions thrown by other branches are added to the first exception as having been - "suppressed by" the first exception; see - Throwable.addSuppresssed(...). + “suppressed by” the first exception; see + Throwable.addSuppressed(...).

Note that a hudson.AbortException, as thrown by failing - steps, will stop and fail the branch but not produce a stack trace. + steps (for example sh with a nonzero exit status), + will stop and fail the branch but not produce a stack trace. This produces a:

       [branchname] Failed in branch branchname
@@ -38,32 +39,31 @@
       message without any details.
     

- To report results from branches to the outer script, use the closure's - access to the outer scope's variables. For example, to run a shell script + To report results from branches to the outer script, use the closure’s + access to the outer scope’s variables. For example, to run a shell script in parallel on each of a list of arguments and produce a map of argument to script stdout:

         def args = ['foo', 'bar', 'baz']
         def results = [:]
         // Produce a map of args to closures that use each arg
-        branches = args.collectEntries { arg -> [(arg): {
+        branches = args.collectEntries { arg -> [arg: {
             def out = sh script: "./my-script.sh '${arg}'", returnStdout: true
-            results << [(arg): out]
-            return null
+            results[arg] = out
           } ] }
-        branches << [failFast: true]
+        branches.failFast = true
         parallel branches
       
- If all the scripts returned 0, the 'results' array contains a map of arg + If all of the branches succeeded, the 'results' array contains a map of arg to shell stdout string. Otherwise parallel terminates the - other branches and re-throws the hudson.AbortException from + other branches and re-throws the Exception from the first failed script.

- Note: Branch closures should just return null. The return + Note: Branch closures may return null or just nothing specific. The return value of the parallel step should be ignored. parallel does capture the return values of closures and return a map of branch name to return value. But relying on this is not - recommended and the behaviour is subject to change; See JENKINS-26033. + recommended and the behaviour is subject to change (JENKINS-26033).