我有一个简单的脚本管道,如下所示:

```groovy

import hudson.model.*

import groovy.json.*

def map = [:]

map['second'] = {

build job: "childPipeline1", propagate: true, wait: true

}

map['third'] = {

build job: "childPipeline2", propagate: true, wait: true

}

try {

parallel map

} catch (Exception e) {

e.getCauses().each {

echo "${it.getShortDescription()}"

}

}

```

实际的地图创建代码是动态的,如下所示:

```groovy

map["${substage}_${subdir}"] = {

build job: "ci_pipeline_${substage}${jobSuffix}", parameters: downstreamParams[subdir], propagate: true

}

```

但是这段代码会抛出一个异常:`org.jenkinsci.plugins.workflow.steps.FlowInterruptedException`。

以下是重构后的代码结构:

```javascript

// Pipeline

const childPipeline1 = spawn('build', ['childPipeline1'], { detached: true });

childPipeline1.stdout.on('data', data => console.log(`Starting building: ${data} #${childPipeline1.pid}`));

childPipeline1.stderr.on('data', data => console.error(`Error in branch third:`, data));

const childPipeline2 = spawn('build', ['childPipeline2'], { detached: true });

childPipeline2.stdout.on('data', data => console.log(`Starting building: ${data} #${childPipeline2.pid}`));

childPipeline2.stderr.on('data', data => console.error(`Error in branch second:`, data));

setTimeout(() => {

childPipeline1.kill();

childPipeline2.kill();

}, 3000);

Promise.all([childPipeline1, childPipeline2])

.then((results) => {

const [result1, result2] = results;

if (result1 && result1.exitCode === null) {

console.log("ChildPipeline1 completed with status SUCCESS");

} else {

throw new Error("ChildPipeline1 build failed");

}

if (result2 && result2.exitCode === null) {

console.log("ChildPipeline2 completed with status SUCCESS");

} else {

throw new Error("ChildPipeline2 build failed");

}

})

.catch((error) => {

console.error(error); // parallel echo childPipeline2 #148 completed with status FAILURE (propagate: false to ignore) End of Pipeline Finished: FAILURE

```java

import hudson.Extension;

import hudson.model.AbstractBuild;

import hudson.model.BuildListener;

import hudson.model.Job;

import hudson.tasks.Builder;

import jenkins.model.Jenkins;

@Extension

public class DynamicParallelMapRunner extends Builder {

@Override

public boolean perform(AbstractBuild build, BuildListener listener) throws InterruptedException, IOException {

// Get the job for this build

Job job = build.getProject();

// Run two parallel builds in different branches of the job

for (int i = 0; i < 2; i++) {

job.getBuildersList().add(new childPipeline1(build));

job.getBuildersList().add(new childPipeline2(build));

}

return true;

}

}

```

以下是重构后的内容:

```bash

map["${substage}_${subdir}"] = { try { build job: "ci_pipeline_${substage}${jobSuffix}", parameters: downstreamParams[subdir], propagate: true } catch(Exception e) { e.getCauses().each { echo "${it.getShortDescription()}" }}

```