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
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from interface org.jenkinsci.plugins.workflow.graph.GraphLookupView
GraphLookupView.EnclosingBlocksIterable
-
-
Field Summary
Fields Modifier and Type Field Description protected FlowDurabilityHint
durabilityHint
CheckForNull due to loading pre-durability runs.protected GraphLookupView
internalGraphLookup
-
Constructor Summary
Constructors Constructor Description FlowExecution()
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Deprecated Methods Modifier and Type Method Description abstract void
addListener(GraphListener listener)
Add a listener to changes in the flow graph structure.protected void
afterStepExecutionsResumed()
Called after a restart and any attempts atStepExecution.onResume()
have completed.boolean
blocksRestart()
Determines whether the activity currently being run should block a Jenkins restart.List<BlockStartNode>
findAllEnclosingBlockStarts(FlowNode node)
Return all enclosing block start nodes, as withGraphLookupView.findEnclosingBlockStart(FlowNode)
.BlockStartNode
findEnclosingBlockStart(FlowNode node)
Find the immediately enclosingBlockStartNode
around aFlowNode
abstract Authentication
getAuthentication()
Looks up authentication associated with this flow execution.Throwable
getCauseOfFailure()
If this execution has completed with an error, report that.com.google.common.util.concurrent.ListenableFuture<List<org.jenkinsci.plugins.workflow.steps.StepExecution>>
getCurrentExecutions()
Deprecated.com.google.common.util.concurrent.ListenableFuture<List<org.jenkinsci.plugins.workflow.steps.StepExecution>>
getCurrentExecutions(boolean innerMostOnly)
Yields theStepExecution
s that are currently executing.abstract List<FlowNode>
getCurrentHeads()
In the current flow graph, return all the "head" nodes where the graph is still growing.FlowDurabilityHint
getDurabilityHint()
Get the durability level we're aiming for, or a default value if none is set (defaults may change as implementation evolve).BlockEndNode
getEndNode(BlockStartNode startNode)
Find the end node corresponding to a start node, and can be used to tell if the block is completed.protected GraphLookupView
getInternalGraphLookup()
Eventually this may be overridden if the FlowExecution has a better source of structural information, such as theFlowNode
storage.abstract FlowNode
getNode(String id)
Loads a node by its ID.abstract FlowExecutionOwner
getOwner()
String
getUrl()
Returns the URL of thisFlowExecution
, relative to the context root of Jenkins.abstract void
interrupt(Result r, CauseOfInterruption... causes)
Interrupts the execution of a flow.boolean
isActive(FlowNode node)
Tests if the node is a currently running head, or the start of a block that has not completed executingboolean
isComplete()
Checks whether this flow execution has finished executing completely.abstract boolean
isCurrentHead(FlowNode n)
Short forgetCurrentHeads().contains(n)
but more efficient.Iterable<BlockStartNode>
iterateEnclosingBlocks(FlowNode node)
Provide anIterable
over all enclosing blocks, which can be used similarly toGraphLookupView.findAllEnclosingBlockStarts(FlowNode)
but does lazy fetches rather than materializing a full result.protected void
notifyShutdown()
Perform shutdown-specific logic -- should be invoked by theFlowExecutionOwner.notifyShutdown()
method in response toFlowExecutionList.saveAll()
void
onLoad()
Deprecated.void
onLoad(FlowExecutionOwner owner)
Should be called by the flow owner after it is deserialized.void
removeListener(GraphListener listener)
abstract void
start()
Called afterFlowDefinition.create(FlowExecutionOwner, List)
to initiate the execution.-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface org.jenkinsci.plugins.workflow.graph.FlowActionStorage
loadActions, saveActions
-
-
-
-
Field Detail
-
internalGraphLookup
protected transient GraphLookupView internalGraphLookup
-
durabilityHint
@CheckForNull protected FlowDurabilityHint durabilityHint
CheckForNull due to loading pre-durability runs.
-
-
Method Detail
-
getInternalGraphLookup
protected GraphLookupView getInternalGraphLookup()
Eventually this may be overridden if the FlowExecution has a better source of structural information, such as theFlowNode
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 afterFlowDefinition.create(FlowExecutionOwner, List)
to initiate the execution. This method is not invoked on rehydrated execution. This separation ensures thatFlowExecutionOwner
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 theStepExecution
s that are currently executing.StepExecution
s are persisted as a part of the program state, so its lifecycle is independent ofFlowExecution
, 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 forgetCurrentHeads().contains(n)
but more efficient.
-
getUrl
public String getUrl() throws IOException
Returns the URL of thisFlowExecution
, 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 forStepContext.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:
StepExecution.stop(Throwable)
,Executor.interrupt(Result)
-
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:
AsynchronousExecution.blocksRestart()
-
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 fromFlowEndNode
.
-
getNode
@CheckForNull public abstract FlowNode getNode(String id) throws IOException
Loads a node by its ID. Also gives eachFlowNode
a portion of the URL space.- Throws:
IOException
- See Also:
FlowNode.getId()
-
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, orJenkins.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 interfaceGraphLookupView
- Throws:
IllegalArgumentException
- If the inputFlowNode
does not belong to this execution- See Also:
GraphLookupView.isActive(FlowNode)
-
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 interfaceGraphLookupView
- Returns:
BlockEndNode
matching the given start node, or null if block hasn't completed- Throws:
IllegalArgumentException
- If the inputFlowNode
does not belong to this execution- See Also:
GraphLookupView.getEndNode(BlockStartNode)
-
findEnclosingBlockStart
@CheckForNull @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public BlockStartNode findEnclosingBlockStart(@NonNull FlowNode node)
Description copied from interface:GraphLookupView
Find the immediately enclosingBlockStartNode
around aFlowNode
- Specified by:
findEnclosingBlockStart
in interfaceGraphLookupView
- 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
orFlowEndNode
- Throws:
IllegalArgumentException
- If the inputFlowNode
does not belong to this execution- See Also:
GraphLookupView.findEnclosingBlockStart(FlowNode)
-
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 withGraphLookupView.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 interfaceGraphLookupView
- 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 inputFlowNode
does not belong to this execution- See Also:
GraphLookupView.findAllEnclosingBlockStarts(FlowNode)
-
iterateEnclosingBlocks
@NonNull @Restricted(org.kohsuke.accmod.restrictions.NoExternalUse.class) public Iterable<BlockStartNode> iterateEnclosingBlocks(@NonNull FlowNode node)
Description copied from interface:GraphLookupView
Provide anIterable
over all enclosing blocks, which can be used similarly toGraphLookupView.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 interfaceGraphLookupView
- 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 inputFlowNode
does not belong to this execution- See Also:
GraphLookupView.iterateEnclosingBlocks(FlowNode)
-
notifyShutdown
protected void notifyShutdown()
Perform shutdown-specific logic -- should be invoked by theFlowExecutionOwner.notifyShutdown()
method in response toFlowExecutionList.saveAll()
-
afterStepExecutionsResumed
protected void afterStepExecutionsResumed()
Called after a restart and any attempts atStepExecution.onResume()
have completed. This is a signal that it is safe to resume program execution. By default, does nothing.
-
-