Class FlowExecution

java.lang.Object
org.jenkinsci.plugins.workflow.flow.FlowExecution
All Implemented Interfaces:
FlowActionStorage, GraphLookupView

public abstract class FlowExecution extends Object implements FlowActionStorage, GraphLookupView
State of a currently executing workflow.

This "interface" abstracts away workflow definition language, syntax, or its execution model, but it allows other code to listen on what's going on.

Persistence

FlowExecution must support persistence by XStream, which should capture the state of execution at one point. The expectation is that when the object gets deserialized, it'll start re-executing from that point.

Author:
Kohsuke Kawaguchi, Jesse Glick
  • Field Details

    • internalGraphLookup

      protected transient GraphLookupView internalGraphLookup
    • durabilityHint

      @CheckForNull protected FlowDurabilityHint durabilityHint
      CheckForNull due to loading pre-durability runs.
  • Constructor Details

    • FlowExecution

      public FlowExecution()
  • Method Details

    • getInternalGraphLookup

      protected GraphLookupView getInternalGraphLookup()
      Eventually this may be overridden if the FlowExecution has a better source of structural information, such as the FlowNode storage.
    • getDurabilityHint

      @NonNull public FlowDurabilityHint getDurabilityHint()
      Get the durability level we're aiming for, or a default value if none is set (defaults may change as implementation evolve).
      Returns:
      Durability level we are aiming for with this execution.
    • start

      public abstract void start() throws IOException
      Called after FlowDefinition.create(FlowExecutionOwner, List) to initiate the execution. This method is not invoked on rehydrated execution. This separation ensures that FlowExecutionOwner is functional when this method is called.
      Throws:
      IOException
    • onLoad

      public void onLoad(FlowExecutionOwner owner) throws IOException
      Should be called by the flow owner after it is deserialized.
      Throws:
      IOException
    • onLoad

      @Deprecated public void onLoad()
      Deprecated.
    • getOwner

      public abstract FlowExecutionOwner getOwner()
    • getCurrentHeads

      public abstract List<FlowNode> getCurrentHeads()
      In the current flow graph, return all the "head" nodes where the graph is still growing. If you think of a flow graph as a git repository, these heads correspond to branches.
    • getCurrentExecutions

      public com.google.common.util.concurrent.ListenableFuture<List<org.jenkinsci.plugins.workflow.steps.StepExecution>> getCurrentExecutions(boolean innerMostOnly)
      Yields the StepExecutions that are currently executing.

      StepExecutions are persisted as a part of the program state, so its lifecycle is independent of FlowExecution, hence the asynchrony.

      Think of this as program counters of all the virtual threads.

      The implementation should return results in the order that steps were started, insofar as that makes sense.

      Parameters:
      innerMostOnly - if true, only return the innermost steps; if false, include any block-scoped steps running around them
    • getCurrentExecutions

      @Deprecated public com.google.common.util.concurrent.ListenableFuture<List<org.jenkinsci.plugins.workflow.steps.StepExecution>> getCurrentExecutions()
      Deprecated.
    • isCurrentHead

      public abstract boolean isCurrentHead(FlowNode n)
      Short for getCurrentHeads().contains(n) but more efficient.
    • getUrl

      public String getUrl() throws IOException
      Returns the URL of this FlowExecution, relative to the context root of Jenkins.
      Returns:
      String like "job/foo/32/execution/" with trailing slash but no leading slash.
      Throws:
      IOException
    • interrupt

      public abstract void interrupt(Result r, CauseOfInterruption... causes) throws IOException, InterruptedException
      Interrupts the execution of a flow. If any computation is going on synchronously, it will be interrupted/killed/etc. If it's in a suspended state waiting to be resurrected (such as waiting for StepContext.onSuccess(Object)), then it just marks the workflow as done with the specified status.

      If it's evaluating bodies (see StepContext.newBodyInvoker(), then it's callback needs to be invoked.

      Do not use this from a step. Throw FlowInterruptedException or some other exception instead.

      Throws:
      IOException
      InterruptedException
      See Also:
    • addListener

      public abstract void addListener(GraphListener listener)
      Add a listener to changes in the flow graph structure.
      Parameters:
      listener - a listener to add
    • removeListener

      public void removeListener(GraphListener listener)
    • isComplete

      public boolean isComplete()
      Checks whether this flow execution has finished executing completely.
    • blocksRestart

      public boolean blocksRestart()
      Determines whether the activity currently being run should block a Jenkins restart.
      Returns:
      by default, true
      See Also:
    • getCauseOfFailure

      @CheckForNull public final Throwable getCauseOfFailure()
      If this execution has completed with an error, report that. This is a convenience method to look up the error result from FlowEndNode.
    • getNode

      @CheckForNull public abstract FlowNode getNode(String id) throws IOException
      Loads a node by its ID. Also gives each FlowNode a portion of the URL space.
      Throws:
      IOException
      See Also:
    • getAuthentication

      @NonNull public abstract Authentication getAuthentication()
      Looks up authentication associated with this flow execution. For example, if a flow is configured to be a trusted agent of a user, that would be set here. A flow run triggered by a user manually might be associated with the runtime, or it might not.
      Returns:
      an authentication; ACL.SYSTEM as a fallback, or Jenkins.ANONYMOUS if the flow is supposed to be limited to a specific user but that user cannot now be looked up
    • isActive

      @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public boolean isActive(@NonNull FlowNode node)
      Description copied from interface: GraphLookupView
      Tests if the node is a currently running head, or the start of a block that has not completed executing
      Specified by:
      isActive in interface GraphLookupView
      Throws:
      IllegalArgumentException - If the input FlowNode does not belong to this execution
      See Also:
    • getEndNode

      @CheckForNull @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public BlockEndNode getEndNode(@NonNull BlockStartNode startNode)
      Description copied from interface: GraphLookupView
      Find the end node corresponding to a start node, and can be used to tell if the block is completed.
      Specified by:
      getEndNode in interface GraphLookupView
      Returns:
      BlockEndNode matching the given start node, or null if block hasn't completed
      Throws:
      IllegalArgumentException - If the input FlowNode does not belong to this execution
      See Also:
    • findEnclosingBlockStart

      @CheckForNull @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public BlockStartNode findEnclosingBlockStart(@NonNull FlowNode node)
      Description copied from interface: GraphLookupView
      Find the immediately enclosing BlockStartNode around a FlowNode
      Specified by:
      findEnclosingBlockStart in interface GraphLookupView
      Parameters:
      node - Node to find block enclosing it - note that it this is a BlockStartNode, you will return the start of the block enclosing this one.
      Returns:
      Null if node is a FlowStartNode or FlowEndNode
      Throws:
      IllegalArgumentException - If the input FlowNode does not belong to this execution
      See Also:
    • findAllEnclosingBlockStarts

      @NonNull @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public List<BlockStartNode> findAllEnclosingBlockStarts(@NonNull FlowNode node)
      Description copied from interface: GraphLookupView
      Return all enclosing block start nodes, as with GraphLookupView.findEnclosingBlockStart(FlowNode).

      Usage note:Prefer using GraphLookupView.iterateEnclosingBlocks(FlowNode) unless you know you need ALL blocks, since that can lazy-load.

      Specified by:
      findAllEnclosingBlockStarts in interface GraphLookupView
      Parameters:
      node - Node to find enclosing blocks for
      Returns:
      All enclosing block starts from the nearest-enclosing outward ("inside-out" order), or EMPTY_LIST if this is a start or end node
      Throws:
      IllegalArgumentException - If the input FlowNode does not belong to this execution
      See Also:
    • iterateEnclosingBlocks

      @NonNull @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public Iterable<BlockStartNode> iterateEnclosingBlocks(@NonNull FlowNode node)
      Description copied from interface: GraphLookupView
      Provide an Iterable over all enclosing blocks, which can be used similarly to GraphLookupView.findAllEnclosingBlockStarts(FlowNode) but does lazy fetches rather than materializing a full result. Handy for for-each loops.

      Usage note:Prefer this to GraphLookupView.findAllEnclosingBlockStarts(FlowNode) in most cases since it can evaluate lazily, unless you know you need all enclosing blocks.

      Specified by:
      iterateEnclosingBlocks in interface GraphLookupView
      Parameters:
      node - Node to find enclosing blocks for
      Returns:
      Iterable over enclosing blocks, from the nearest-enclosing outward ("inside-out" order)
      Throws:
      IllegalArgumentException - If the input FlowNode does not belong to this execution
      See Also:
    • notifyShutdown

      @Deprecated protected void notifyShutdown()
      Deprecated.
      No longer used.
    • afterStepExecutionsResumed

      protected void afterStepExecutionsResumed()
      Called after a restart and any attempts at StepExecution.onResume() have completed. This is a signal that it is safe to resume program execution. By default, does nothing.