use of org.jenkinsci.plugins.workflow.support.storage.FlowNodeStorage in project workflow-cps-plugin by jenkinsci.
the class CpsFlowExecution method checkpoint.
/**
* Save everything we can to disk - program, run, flownodes.
* @param shuttingDown True if this checkpoint is happening because Jenkins is shutting down, false if it is happening because execution was paused.
*/
private void checkpoint(boolean shuttingDown) {
if (isComplete() || this.getDurabilityHint().isPersistWithEveryStep()) {
// Nothing to persist OR we've already persisted it along the way.
return;
}
LOGGER.log(Level.INFO, "Attempting to save a checkpoint of all data for {0}{1}", new Object[] { this, shuttingDown ? " before shutdown" : "" });
boolean persistOk = true;
FlowNodeStorage storage = getStorage();
if (storage != null) {
try {
// Node storage must be flushed first so program can be restored
storage.flush();
} catch (IOException ioe) {
persistOk = false;
LOGGER.log(Level.WARNING, "Error persisting FlowNode storage for: " + this, ioe);
}
// Try to ensure we've saved the appropriate things -- the program is the last stumbling block.
try {
final CompletableFuture<Void> myOutcome = new CompletableFuture<>();
LOGGER.log(Level.FINE, "About to try to checkpoint the program for: {0}", this);
if (programPromise != null && programPromise.isDone()) {
runInCpsVmThread(new FutureCallback<CpsThreadGroup>() {
@Override
public void onSuccess(CpsThreadGroup result) {
try {
LOGGER.log(Level.FINE, "Trying to save program for: {0}", CpsFlowExecution.this);
result.saveProgramIfPossible(true);
LOGGER.log(Level.FINE, "Finished saving program for: {0}", CpsFlowExecution.this);
myOutcome.complete(null);
} catch (Exception ex) {
// Logged at Level.WARNING when we call `myOutcome.get` and it throws an exception.
myOutcome.completeExceptionally(ex);
}
}
@Override
public void onFailure(Throwable t) {
// Logged at Level.WARNING when we call `myOutcome.get` and it throws an exception.
myOutcome.completeExceptionally(t);
}
});
myOutcome.get(30, TimeUnit.SECONDS);
LOGGER.log(Level.FINE, "Successfully saved program for: {0}", this);
} else {
persistOk = false;
LOGGER.log(Level.WARNING, "Unable to persist program because it was never loaded for: {0}", this);
}
} catch (TimeoutException te) {
persistOk = false;
LOGGER.log(Level.WARNING, "Timeout persisting program for: " + this, te);
} catch (ExecutionException | InterruptedException ex) {
persistOk = false;
LOGGER.log(Level.WARNING, "Error saving program for: " + this, ex);
}
try {
// Flush node storage just in case the Program mutated it, just to be sure
storage.flush();
LOGGER.log(Level.FINE, "Successfully did final flush of storage for: {0}", this);
} catch (IOException ioe) {
persistOk = false;
LOGGER.log(Level.WARNING, "Error persisting FlowNode storage for: " + this, ioe);
}
persistedClean = persistOk;
try {
saveOwner();
} catch (Exception ex) {
persistOk = false;
LOGGER.log(Level.WARNING, "Error saving build for: " + this, ex);
}
} else {
persistOk = false;
LOGGER.log(Level.WARNING, "No FlowNode storage for: {0}", this);
}
if (persistOk) {
LOGGER.log(Level.INFO, "Successfully checkpointed {0}{1}", new Object[] { this, (shuttingDown ? " before shutdown" : "") });
} else {
LOGGER.log(Level.WARNING, "Unable to successfully checkpoint {0}{1}", new Object[] { this, (shuttingDown ? " before shutdown, so this build will probably fail when Jenkins restarts" : "") });
}
}
use of org.jenkinsci.plugins.workflow.support.storage.FlowNodeStorage in project workflow-cps-plugin by jenkinsci.
the class CpsFlowExecution method checkpoint.
/**
* Save everything we can to disk - program, run, flownodes.
*/
private void checkpoint() {
if (isComplete() || this.getDurabilityHint().isPersistWithEveryStep()) {
// Nothing to persist OR we've already persisted it along the way.
return;
}
boolean persistOk = true;
FlowNodeStorage storage = getStorage();
if (storage != null) {
// Try to ensure we've saved the appropriate things -- the program is the last stumbling block.
try {
final SettableFuture<Void> myOutcome = SettableFuture.create();
if (programPromise != null && programPromise.isDone()) {
runInCpsVmThread(new FutureCallback<CpsThreadGroup>() {
@Override
public void onSuccess(CpsThreadGroup result) {
try {
result.saveProgramIfPossible(true);
myOutcome.set(null);
} catch (Exception ex) {
LOGGER.log(Level.WARNING, "Error persisting program: " + ex);
myOutcome.setException(ex);
}
}
@Override
public void onFailure(Throwable t) {
myOutcome.setException(t);
}
});
myOutcome.get(30, TimeUnit.SECONDS);
}
} catch (TimeoutException te) {
persistOk = false;
LOGGER.log(Level.WARNING, "Timeout persisting program at execution checkpoint", te);
} catch (ExecutionException | InterruptedException ex) {
persistOk = false;
LOGGER.log(Level.FINE, "Error saving program, that should be handled elsewhere.", ex);
}
try {
storage.flush();
} catch (IOException ioe) {
persistOk = false;
LOGGER.log(Level.WARNING, "Error persisting FlowNode storage before shutdown", ioe);
}
persistedClean = persistOk;
saveOwner();
}
}
use of org.jenkinsci.plugins.workflow.support.storage.FlowNodeStorage in project workflow-cps-plugin by jenkinsci.
the class CpsFlowExecution method createStorage.
private TimingFlowNodeStorage createStorage() throws IOException {
FlowNodeStorage wrappedStorage;
FlowDurabilityHint hint = getDurabilityHint();
wrappedStorage = (hint.isPersistWithEveryStep()) ? new SimpleXStreamFlowNodeStorage(this, getStorageDir()) : new BulkFlowNodeStorage(this, getStorageDir());
return new TimingFlowNodeStorage(wrappedStorage);
}
use of org.jenkinsci.plugins.workflow.support.storage.FlowNodeStorage in project workflow-cps-plugin by jenkinsci.
the class CpsFlowExecution method maybeAutoPersistNode.
/**
* Invoke me to toggle autopersist back on for steps that delay it.
*/
public static void maybeAutoPersistNode(@NonNull FlowNode node) {
try {
FlowExecution exec = node.getExecution();
if (exec instanceof CpsFlowExecution) {
if (exec.getDurabilityHint().isPersistWithEveryStep()) {
FlowNodeStorage exc = ((CpsFlowExecution) exec).getStorage();
exc.autopersist(node);
}
}
} catch (IOException ioe) {
LOGGER.log(Level.WARNING, "Attempt to persist triggered IOException for node " + node.getId(), ioe);
}
}
use of org.jenkinsci.plugins.workflow.support.storage.FlowNodeStorage in project workflow-cps-plugin by jenkinsci.
the class FlowDurabilityTest method assertBaseStorageType.
static void assertBaseStorageType(FlowExecution exec, Class<? extends FlowNodeStorage> storageClass) throws Exception {
if (exec instanceof CpsFlowExecution) {
FlowNodeStorage store = ((CpsFlowExecution) exec).getStorage();
if (store instanceof CpsFlowExecution.TimingFlowNodeStorage) {
Field f = CpsFlowExecution.TimingFlowNodeStorage.class.getDeclaredField("delegate");
f.setAccessible(true);
FlowNodeStorage delegateStore = (FlowNodeStorage) (f.get(store));
Assert.assertEquals(storageClass.toString(), delegateStore.getClass().toString());
}
}
}
Aggregations