/** * Applies only to the specific subtypes. */ public static <T extends StepExecution> ListenableFuture<?> applyAll(final Class<T> type, final Function<T,Void> f) { return applyAll(new Function<StepExecution, Void>() { @Override public Void apply(StepExecution e) { if (type.isInstance(e)) f.apply(type.cast(e)); return null; } }); }
@Override public void onSuccess(List<StepExecution> result) { LOGGER.log(FINE, "Will resume {0}", result); for (StepExecution se : result) { se.onResume(); } }
/** * If the computation is going synchronously, try to cancel that. */ @Override public void stop(Throwable cause) throws Exception { stopping = true; if (task != null) { task.cancel(true); } super.stop(cause); }
private FilePath loadFileFromWorkspace(StepExecution stepExecution, String file) { FilePath workspace; try { workspace = stepExecution.getContext().get(FilePath.class); } catch (IOException e) { throw new RuntimeException(e); } catch (InterruptedException e) { Thread.interrupted(); throw new RuntimeException(e); } return workspace.child(file); }
/** * Stops the execution of this thread. If it's paused to wait for the completion of {@link StepExecution}, * call {@link StepExecution#stop(Throwable)} to give it a chance to clean up. * * <p> * If the execution is not inside a step (meaning it's paused in a safe point), then have the CPS thread * throw a given {@link Throwable} to break asap. */ @CpsVmThreadOnly public void stop(Throwable t) { StepExecution s = getStep(); // this is the part that should run in CpsVmThread if (s == null) { // if it's not running inside a StepExecution, we need to set an interrupt flag // and interrupt at an earliest convenience Outcome o = new Outcome(null, t); if (resumeValue==null) { resume(o); } else { // this thread was already resumed, so just overwrite the value with a Throwable resumeValue = o; } return; } try (Timeout timeout = Timeout.limit(30, TimeUnit.SECONDS)) { s.stop(t); } catch (Exception e) { t.addSuppressed(e); s.getContext().onFailure(t); } }
/** * Given a list of {@link CpsThread}s that share the same {@link FlowHead}, in the order * from outer to inner, reconstruct the thread stack. */ private ThreadInfo(List<CpsThread> e) { CpsThread head = e.get(e.size() - 1); headline = "Thread #" + head.id; ListIterator<CpsThread> itr = e.listIterator(e.size()); while (itr.hasPrevious()) { CpsThread t = itr.previous(); StepExecution s = t.getStep(); if (s !=null) { StepDescriptor d = ((CpsStepContext) s.getContext()).getStepDescriptor(); if (d != null) { String status = s.getStatusBounded(3, TimeUnit.SECONDS); if (status != null) { stack.add(new StackTraceElement("DSL", d.getFunctionName(), status, -1)); } else { stack.add(new StackTraceElement("DSL", d.getFunctionName(), null, -2)); } } } stack.addAll(t.getStackTrace()); } }
@Override public String call() throws Exception { return getStatus(); } });
/** * May be called if someone asks a running step to abort. * <p> * Just like {@link Thread#interrupt()}, * the step might not honor the request immediately. * Multiple stop requests might be sent. * It is always responsible for calling {@link StepContext#onSuccess(Object)} or (more likely) * {@link StepContext#onFailure(Throwable)} eventually, * whether or not it was asked to stop. * <p> * The default behavior is to call {@link StepContext#onFailure} immediately. * This may be overridden by non-block-scoped steps which wish to halt some processing prior to failing the step, * or even to send a cancellation signal to some process but leave the step running until that is handled gracefully. * Block-scoped steps which merely call their bodies generally need not override this method, * as the interrupt will be sent to the step(s) actually running at the time * (so no special call to {@link BodyExecution#cancel(Throwable)} is needed), * though an override may be necessary if it is possible for there to be no body currently running. * <p> * This method is meant to be used by {@code FlowExecution}, not called from UI or other human requests to pause. * Use {@link BodyExecution#cancel(Throwable)} for programmatic cancellation of bodies. * * @param cause * Contextual information that lets the step know what resulted in stopping an executing step, * passed in the hope that this will assist diagnostics. */ public void stop(@Nonnull Throwable cause) throws Exception { getContext().onFailure(cause); }
@Override public String call() throws Exception { return getStatus(); } });
/** * May be called if someone asks a running step to abort. * <p> * Just like {@link Thread#interrupt()}, * the step might not honor the request immediately. * Multiple stop requests might be sent. * It is always responsible for calling {@link StepContext#onSuccess(Object)} or (more likely) * {@link StepContext#onFailure(Throwable)} eventually, * whether or not it was asked to stop. * <p> * The default behavior is to call {@link StepContext#onFailure} immediately. * This may be overridden by non-block-scoped steps which wish to halt some processing prior to failing the step, * or even to send a cancellation signal to some process but leave the step running until that is handled gracefully. * Block-scoped steps which merely call their bodies generally need not override this method, * as the interrupt will be sent to the step(s) actually running at the time * (so no special call to {@link BodyExecution#cancel(Throwable)} is needed), * though an override may be necessary if it is possible for there to be no body currently running. * <p> * This method is meant to be used by {@code FlowExecution}, not called from UI or other human requests to pause. * Use {@link BodyExecution#cancel(Throwable)} for programmatic cancellation of bodies. * * @param cause * Contextual information that lets the step know what resulted in stopping an executing step, * passed in the hope that this will assist diagnostics. */ public void stop(@Nonnull Throwable cause) throws Exception { getContext().onFailure(cause); }
/** * Applies only to the specific subtypes. */ public static <T extends StepExecution> ListenableFuture<?> applyAll(final Class<T> type, final Function<T,Void> f) { return applyAll(new Function<StepExecution, Void>() { @Override public Void apply(StepExecution e) { if (type.isInstance(e)) f.apply(type.cast(e)); return null; } }); }
/** * If the computation is going synchronously, try to cancel that. */ @Override public void stop(Throwable cause) throws Exception { stopCause = cause; if (task != null) { task.cancel(true); } super.stop(cause); }
@Override public void onResume() { super.onResume(); value = "two"; } }
@Override public void onSuccess(List<StepExecution> l) { for (StepExecution e : Iterators.reverse(l)) { StepContext context = e.getContext(); context.onFailure(x); try { FlowNode n = context.get(FlowNode.class); if (n != null) { owner.getListener().getLogger().println("Terminating " + n.getDisplayFunctionName()); } } catch (Exception x) { LOGGER.log(Level.FINE, null, x); } } }
private static void retry(final String id, final StepContext context) { StepExecution.applyAll(Execution.class, new Function<Execution, Void>() { @Override public Void apply(@Nonnull Execution execution) { if (execution.id.equals(id)) { execution.retry(context); } return null; } }); }
/** * If the computation is going synchronously, try to cancel that. */ @Override public void stop(Throwable cause) throws Exception { if (task != null) { stopCause = cause; task.cancel(true); } super.stop(cause); }
@Override // TODO Revisit for JENKINS-40161 public void onResume() { super.onResume(); LOGGER.log(Level.FINE, "onResume"); try { KubernetesNodeContext nodeContext = new KubernetesNodeContext(getContext()); client = nodeContext.connectToCloud(); decorator.setKubernetesClient(client); } catch (Exception e) { ContainerStepExecution.this.getContext().onFailure(e); } }
@Override public void run() { assert currentExecutions.isDone(); try { FlowNode outer = getContext().get(FlowNode.class); // timeout for (StepExecution exec : currentExecutions.get()) { FlowNode inner = exec.getContext().get(FlowNode.class); // some deadbeat step, perhaps LinearBlockHoppingScanner scanner = new LinearBlockHoppingScanner(); scanner.setup(inner); for (FlowNode enclosing : scanner) { if (enclosing.equals(outer)) { exec.getContext().onFailure(death); break; } } } } catch (IOException | InterruptedException | ExecutionException x) { LOGGER.log(Level.WARNING, null, x); } } }, MoreExecutors.sameThreadExecutor());
@Override public Void call() throws RuntimeException { StepExecution.applyAll(TimeoutStepExecution.class, e -> { if (id.equals(e.id)) { e.resetTimer(); } return null; }); return null; }
s.stop(cause); } catch (Exception e) { LOGGER.log(Level.WARNING, "Failed to stop the body execution in response to the failure of the parent");