use of org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback in project workflow-cps-plugin by jenkinsci.
the class CpsBodyExecution method launch.
/**
* Starts evaluating the body.
*
* If the body is a synchronous closure, this method evaluates the closure synchronously.
* Otherwise, the body is asynchronous and the method schedules another thread to evaluate the body.
*
* @param currentThread
* The thread whose context the new thread will inherit.
*/
@CpsVmThreadOnly
/*package*/
void launch(CpsBodyInvoker params, CpsThread currentThread, FlowHead head) {
if (isLaunched())
throw new IllegalStateException("Already launched");
StepStartNode sn = addBodyStartFlowNode(head);
for (Action a : params.startNodeActions) {
if (a != null)
sn.addAction(a);
}
head.setNewHead(sn);
CpsFlowExecution.maybeAutoPersistNode(sn);
StepContext sc = new CpsBodySubContext(context, sn);
for (BodyExecutionCallback c : callbacks) {
c.onStart(sc);
}
try {
// TODO: handle arguments to closure
Object x = params.body.getBody(currentThread).call();
// pointless synchronization to make findbugs happy. This is already done, so there's no cancelling this anyway.
synchronized (this) {
this.thread = currentThread;
}
onSuccess.receive(x);
} catch (CpsCallableInvocation e) {
// execute this closure asynchronously
// TODO: does it make sense that the new thread shares the same head?
CpsThread t = currentThread.group.addThread(createContinuable(currentThread, e), head, ContextVariableSet.from(currentThread.getContextVariables(), params.contextOverrides));
// due to earlier cancellation
synchronized (this) {
t.resume(new Outcome(null, stopped));
assert this.thread == null;
this.thread = t;
}
} catch (Throwable t) {
// body has completed synchronously and abnormally
synchronized (this) {
this.thread = currentThread;
}
onFailure.receive(t);
}
}
Aggregations