Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-26034

Option to interrupt remaining branches when one branch fails

    • Icon: Improvement Improvement
    • Resolution: Fixed
    • Icon: Major Major
    • pipeline
    • None
    • workflow plugin 1.1

      As recorded in https://groups.google.com/d/msg/jenkinsci-dev/kgEc7vZQgi0/IC1rH_6KwNYJ:

      Our deploy process currently builds deploy artifacts and runs tests at the same time. I see how we could implement that using workflow via the 'parallel' step. However, we also want the behavior that if and when build-artifacts fails, it immediately cancels the running tests and fails the deploy job; and likewise if the tests fail, it immediately cancels the building of artifacts and fails the deploy job. If both succeed, then the deploy job continues.

      This is a feature request to implement this sibling-cancel: with a flag (or perhaps as the default, though that's kinda scary), if one of the jobs in parallel() fails, then parallel cancels the other jobs.

      It sounds like parallel returns a map from job-label to job-status. I think under this behavior, the job-status would be "failed" for the job that failed, and "cancelled" for the sibling jobs that were cancelled.

          [JENKINS-26034] Option to interrupt remaining branches when one branch fails

          Jesse Glick added a comment -

          It sounds like parallel returns a map from job-label to job-status.

          Currently to branch return value (not a status per se), but see my comment in JENKINS-26033.

          the job-status would be "failed" for the job that failed, and "cancelled" for the sibling jobs that were cancelled.

          There is only one “job”, the workflow as a whole, a build of which is marked as a failure if any of the parallel branches fail—unless you have a try/catch block outside parallel which does something else.

          Jesse Glick added a comment - It sounds like parallel returns a map from job-label to job-status. Currently to branch return value (not a status per se), but see my comment in JENKINS-26033 . the job-status would be "failed" for the job that failed, and "cancelled" for the sibling jobs that were cancelled. There is only one “job”, the workflow as a whole, a build of which is marked as a failure if any of the parallel branches fail—unless you have a try / catch block outside parallel which does something else.

          Sorry, I knew I'd get the terminology wrong!

          It sounds from JENKINS-26033 that you're leaning towards not having a (meaningful) return value from 'branch'. So if I want to record the fact a particular branch failed, I'd have to swallow the exception and rethrow (to cause the sibling-cancel) – at least, I assume the rethrow would cause the sibling-cancel.

          Just thinking out loud about the following use-case: I want to run two tasks in parallel. If either one fails, I want to cancel the other, and then continue executing my job. How would I do that in a world where 'cancel_siblings' was an option to 'parallel'. I guess it would be something like this:

          def one_failed, two_failed;
          try {
             parallel one: {
                try {
                    ...
                } catch (x) {
                    one_failed = true
                    // Need to rethrow to cause parallel to cancel job two
                    rethrow             // I assume this is a thing?
                }
             }, two: {
                try {
                    ...
                } catch (x) {
                    two_failed = true
                    rethrow
                }
             }
          } catch (x) {
          }
          
          ... continue on, looking at one_failed and two_failed if needed ...
          

          It's a little messy but I believe it works. I doubt this is a super-common case, so as long as it's possible I think this design works for our needs, at least.

          Craig Silverstein added a comment - Sorry, I knew I'd get the terminology wrong! It sounds from JENKINS-26033 that you're leaning towards not having a (meaningful) return value from 'branch'. So if I want to record the fact a particular branch failed, I'd have to swallow the exception and rethrow (to cause the sibling-cancel) – at least, I assume the rethrow would cause the sibling-cancel. Just thinking out loud about the following use-case: I want to run two tasks in parallel. If either one fails, I want to cancel the other, and then continue executing my job. How would I do that in a world where 'cancel_siblings' was an option to 'parallel'. I guess it would be something like this: def one_failed, two_failed; try { parallel one: { try { ... } catch (x) { one_failed = true // Need to rethrow to cause parallel to cancel job two rethrow // I assume this is a thing? } }, two: { try { ... } catch (x) { two_failed = true rethrow } } } catch (x) { } ... continue on, looking at one_failed and two_failed if needed ... It's a little messy but I believe it works. I doubt this is a super-common case, so as long as it's possible I think this design works for our needs, at least.

          Jesse Glick added a comment -

          if I want to record the fact a particular branch failed

          You mean, beyond the build log and any flow graph visualizations that show this information, you want to base some decision for the remainder of the flow on which part failed, rather than having the whole build abort then and there. You could do something like

          def oneErr, twoErr
          try {
            parallel one: {
              try {
                …
              } catch (x) {
                oneErr = x
                throw x // or anything for that matter
              }
            }, two: {
              try {
                …
              } catch (x) {
                twoErr = x
                throw x
              }
            }
          } catch (x) {
            if (oneErr) {
              …
            } else if (twoErr) {
              …
            } else {
              // something else went wrong, die
              throw x
            }
          }
          

          Perhaps not the most concise idiom, but the purpose is probably apparent to anyone reading it, and it is not hard to see how you could customize some aspects of the behavior.

          Jesse Glick added a comment - if I want to record the fact a particular branch failed You mean, beyond the build log and any flow graph visualizations that show this information, you want to base some decision for the remainder of the flow on which part failed, rather than having the whole build abort then and there. You could do something like def oneErr, twoErr try { parallel one: { try { … } catch (x) { oneErr = x throw x // or anything for that matter } }, two: { try { … } catch (x) { twoErr = x throw x } } } catch (x) { if (oneErr) { … } else if (twoErr) { … } else { // something else went wrong, die throw x } } Perhaps not the most concise idiom, but the purpose is probably apparent to anyone reading it, and it is not hard to see how you could customize some aspects of the behavior.

          Right, looks like we came up with the exact same approach! Works for me.

          Craig Silverstein added a comment - Right, looks like we came up with the exact same approach! Works for me.

          Code changed in jenkins
          User: James Nord
          Path:
          aggregator/src/test/java/org/jenkinsci/plugins/workflow/steps/parallel/ParallelStepTest.java
          cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep.java
          cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStepExecution.java
          cps/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/config.jelly
          http://jenkins-ci.org/commit/workflow-plugin/76f64222588c215e6577972971aada9bf871d811
          Log:
          JENKINS-26034 add option to fail fast on parallel branch failure.

          Added an option "failFast: true" to the parallel step options that
          will terminate all running branches inside a parallel step if one of the
          branches fails.

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: James Nord Path: aggregator/src/test/java/org/jenkinsci/plugins/workflow/steps/parallel/ParallelStepTest.java cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep.java cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStepExecution.java cps/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/config.jelly http://jenkins-ci.org/commit/workflow-plugin/76f64222588c215e6577972971aada9bf871d811 Log: JENKINS-26034 add option to fail fast on parallel branch failure. Added an option "failFast: true" to the parallel step options that will terminate all running branches inside a parallel step if one of the branches fails.

          Code changed in jenkins
          User: Jesse Glick
          Path:
          CHANGES.md
          aggregator/src/test/java/org/jenkinsci/plugins/workflow/steps/parallel/ParallelStepTest.java
          cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep.java
          cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStepExecution.java
          cps/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/config.jelly
          http://jenkins-ci.org/commit/workflow-plugin/841d231280bb2470352f4b472bdf89c328cda304
          Log:
          Merge pull request #88 from jtnord/failFast

          JENKINS-26034 add option to fail fast on parallel branch failure.

          Compare: https://github.com/jenkinsci/workflow-plugin/compare/f2b787c9d2a8...841d231280bb

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: Jesse Glick Path: CHANGES.md aggregator/src/test/java/org/jenkinsci/plugins/workflow/steps/parallel/ParallelStepTest.java cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep.java cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStepExecution.java cps/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/config.jelly http://jenkins-ci.org/commit/workflow-plugin/841d231280bb2470352f4b472bdf89c328cda304 Log: Merge pull request #88 from jtnord/failFast JENKINS-26034 add option to fail fast on parallel branch failure. Compare: https://github.com/jenkinsci/workflow-plugin/compare/f2b787c9d2a8...841d231280bb

          Code changed in jenkins
          User: James Nord
          Path:
          aggregator/src/test/java/org/jenkinsci/plugins/workflow/steps/parallel/ParallelStepTest.java
          cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep.java
          cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStepExecution.java
          cps/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/config.jelly
          http://jenkins-ci.org/commit/workflow-cps-plugin/c8c668f2b60a19c33add92e2b14345f23f58aabc
          Log:
          JENKINS-26034 add option to fail fast on parallel branch failure.

          Added an option "failFast: true" to the parallel step options that
          will terminate all running branches inside a parallel step if one of the
          branches fails.

          Originally-Committed-As: 76f64222588c215e6577972971aada9bf871d811

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: James Nord Path: aggregator/src/test/java/org/jenkinsci/plugins/workflow/steps/parallel/ParallelStepTest.java cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep.java cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStepExecution.java cps/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/config.jelly http://jenkins-ci.org/commit/workflow-cps-plugin/c8c668f2b60a19c33add92e2b14345f23f58aabc Log: JENKINS-26034 add option to fail fast on parallel branch failure. Added an option "failFast: true" to the parallel step options that will terminate all running branches inside a parallel step if one of the branches fails. Originally-Committed-As: 76f64222588c215e6577972971aada9bf871d811

          Code changed in jenkins
          User: Jesse Glick
          Path:
          aggregator/src/test/java/org/jenkinsci/plugins/workflow/steps/parallel/ParallelStepTest.java
          cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep.java
          cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStepExecution.java
          cps/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/config.jelly
          http://jenkins-ci.org/commit/workflow-cps-plugin/246c2d2a0f97436ea880637ac33cc8bdcbb3e298
          Log:
          Merge pull request #88 from jtnord/failFast

          JENKINS-26034 add option to fail fast on parallel branch failure.
          Originally-Committed-As: 841d231280bb2470352f4b472bdf89c328cda304

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: Jesse Glick Path: aggregator/src/test/java/org/jenkinsci/plugins/workflow/steps/parallel/ParallelStepTest.java cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep.java cps/src/main/java/org/jenkinsci/plugins/workflow/cps/steps/ParallelStepExecution.java cps/src/main/resources/org/jenkinsci/plugins/workflow/cps/steps/ParallelStep/config.jelly http://jenkins-ci.org/commit/workflow-cps-plugin/246c2d2a0f97436ea880637ac33cc8bdcbb3e298 Log: Merge pull request #88 from jtnord/failFast JENKINS-26034 add option to fail fast on parallel branch failure. Originally-Committed-As: 841d231280bb2470352f4b472bdf89c328cda304

          We have `failFast` now!

          Craig Silverstein added a comment - We have `failFast` now!

            Unassigned Unassigned
            csilvers Craig Silverstein
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: