Skip to content

Commit

Permalink
Better document and test @NonCPS.
Browse files Browse the repository at this point in the history
  • Loading branch information
jglick committed Sep 21, 2015
1 parent 0bf201b commit 65a0000
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
25 changes: 25 additions & 0 deletions TUTORIAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,31 @@ node('remote') {
}
```

However the safest approach is to isolate use of nonserializable state inside a method marked with the annotation `@NonCPS`.
Such a method will be treated as “native” by the Workflow engine, and its local variables never saved.
However it may _not_ make any calls to Workflow steps, so the `readFile` call must be pulled out:

```groovy
node('remote') {
git url: 'https://github.com/jglick/simple-maven-project-with-tests.git'
def v = version(readFile('pom.xml'))
if (v) {
echo "Building version ${v}"
}
def mvnHome = tool 'M3'
sh "${mvnHome}/bin/mvn -B -Dmaven.test.failure.ignore verify"
step([$class: 'ArtifactArchiver', artifacts: '**/target/*.jar', fingerprint: true])
step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
}
@NonCPS
def version(text) {
def matcher = text =~ '<version>(.+)</version>'
matcher ? matcher[0][1] : null
}
```

Here the logic inside the `version` function is run by the normal Groovy runtime, so any local variables are permitted.

## Multiple threads

Workflows can use a `parallel` step to perform multiple actions at once.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,22 @@ public void stop(Throwable cause) throws Exception {
});
}

@Test public void nonCps() {
story.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
p = jenkins().createProject(WorkflowJob.class, "demo");
p.setDefinition(new CpsFlowDefinition(
"echo \"first parse: ${parse('foo <version>1.0</version> bar')}\"\n" +
"echo \"second parse: ${parse('foo bar')}\"\n" +
"@NonCPS def parse(text) {\n" +
" def matcher = text =~ '<version>(.+)</version>'\n" +
" matcher ? matcher[0][1] : null\n" +
"}\n", true));
b = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0));
story.j.assertLogContains("first parse: 1.0", b);
story.j.assertLogContains("second parse: null", b);
}
});
}

}

0 comments on commit 65a0000

Please sign in to comment.