Thinking yet more: I think CpsFlowExecution#done should be in CpsFlowExecution.ConverterImpl#marshal and #unmarshal - it's weird that it's not persisted currently, at least to me. With that in place, CpsFlowExecution#isComplete() would be true for completed builds at load time. CpsFlowExecution#onLoad(FlowExecutionOwner) would call initializeStorage() and load the flow nodes, but not go into loadProgramAsync and onwards to parsing/transformation/etc. That at least deals with some of the issues caused by WorkflowRun#execution being eagerly loaded. So then the question is whether we want to bother with the initializeStorage() call at all in lazy-loading situations. Assuming that we don't want to do that, then we could change to something like this in WorkflowRun#onLoad:
FlowExecution fetchedExecution = execution;
if (fetchedExecution != null && !fetchedExecution.isComplete()) {
try {
if (getParent().isResumeBlocked() && execution instanceof BlockableResume) {
((BlockableResume) execution).setResumeBlocked(true);
}
fetchedExecution.onLoad(new Owner(this));
} catch (Exception x) {
LOGGER.log(Level.WARNING, null, x);
execution = null; }
}
fetchedExecution = execution;
if (fetchedExecution != null) {
...
...i.e., skipping calling fetchedExecution.onLoad(new Owner(this)) for a completed FlowExecution. The following if block already has a check for !fetchedExecution.isComplete() before doing some of its body, so we probably wouldn't need to do anything there, I guess?
Code changed in jenkins
User: Jesse Glick
Path:
src/main/java/org/jenkinsci/plugins/workflow/job/WorkflowRun.java
http://jenkins-ci.org/commit/workflow-job-plugin/bbec76226dcbd01622a6f29a753d1e72af49e03f
Log:
Noting
JENKINS-45585.