Search in sources :

Example 1 with FlowNodeStorage

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" : "") });
    }
}
Also used : InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) FlowInterruptedException(org.jenkinsci.plugins.workflow.steps.FlowInterruptedException) UsernameNotFoundException(org.acegisecurity.userdetails.UsernameNotFoundException) InterruptedIOException(java.io.InterruptedIOException) AbortException(hudson.AbortException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) FlowInterruptedException(org.jenkinsci.plugins.workflow.steps.FlowInterruptedException) CompletableFuture(java.util.concurrent.CompletableFuture) ExecutionException(java.util.concurrent.ExecutionException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) BulkFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.BulkFlowNodeStorage) FlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.FlowNodeStorage) SimpleXStreamFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.SimpleXStreamFlowNodeStorage) TimeoutException(java.util.concurrent.TimeoutException)

Example 2 with FlowNodeStorage

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();
    }
}
Also used : IOException(java.io.IOException) FlowInterruptedException(org.jenkinsci.plugins.workflow.steps.FlowInterruptedException) UsernameNotFoundException(org.acegisecurity.userdetails.UsernameNotFoundException) AbortException(hudson.AbortException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) FlowInterruptedException(org.jenkinsci.plugins.workflow.steps.FlowInterruptedException) ExecutionException(java.util.concurrent.ExecutionException) BulkFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.BulkFlowNodeStorage) FlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.FlowNodeStorage) SimpleXStreamFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.SimpleXStreamFlowNodeStorage) TimeoutException(java.util.concurrent.TimeoutException)

Example 3 with FlowNodeStorage

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);
}
Also used : BulkFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.BulkFlowNodeStorage) SimpleXStreamFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.SimpleXStreamFlowNodeStorage) FlowDurabilityHint(org.jenkinsci.plugins.workflow.flow.FlowDurabilityHint) BulkFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.BulkFlowNodeStorage) FlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.FlowNodeStorage) SimpleXStreamFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.SimpleXStreamFlowNodeStorage)

Example 4 with FlowNodeStorage

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);
    }
}
Also used : FlowExecution(org.jenkinsci.plugins.workflow.flow.FlowExecution) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) BulkFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.BulkFlowNodeStorage) FlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.FlowNodeStorage) SimpleXStreamFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.SimpleXStreamFlowNodeStorage)

Example 5 with FlowNodeStorage

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());
        }
    }
}
Also used : Field(java.lang.reflect.Field) FlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.FlowNodeStorage) BulkFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.BulkFlowNodeStorage) SimpleXStreamFlowNodeStorage(org.jenkinsci.plugins.workflow.support.storage.SimpleXStreamFlowNodeStorage)

Aggregations

BulkFlowNodeStorage (org.jenkinsci.plugins.workflow.support.storage.BulkFlowNodeStorage)5 FlowNodeStorage (org.jenkinsci.plugins.workflow.support.storage.FlowNodeStorage)5 SimpleXStreamFlowNodeStorage (org.jenkinsci.plugins.workflow.support.storage.SimpleXStreamFlowNodeStorage)5 IOException (java.io.IOException)3 AbortException (hudson.AbortException)2 InterruptedIOException (java.io.InterruptedIOException)2 ExecutionException (java.util.concurrent.ExecutionException)2 TimeoutException (java.util.concurrent.TimeoutException)2 UsernameNotFoundException (org.acegisecurity.userdetails.UsernameNotFoundException)2 FlowInterruptedException (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException)2 Field (java.lang.reflect.Field)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)1 FlowDurabilityHint (org.jenkinsci.plugins.workflow.flow.FlowDurabilityHint)1 FlowExecution (org.jenkinsci.plugins.workflow.flow.FlowExecution)1