Class FlowNodeCounter

java.lang.Object
com.aquima.interactions.flow.model.FlowNodeCounter

public class FlowNodeCounter extends Object
Counts flow nodes reached during the execution of a flow.

This counter is composed of two sub-counters:

  • a global counter which counts how many times a subflow node was entered and exited
  • a local counter - scoped to each (sub)flow, counts how many times nodes in the current flow have been reached

The counter can be used to detect potential infinite loops or infinite recursion. Each time a flow node is reached, it should be registered in this counter using register(NodeID). When a flow node is entered, this counter must be notified using onFlowEnter(NodeID), and when a flow node is exited, the counter should be notified using onFlowExit(NodeID). When the flow associated with a flow node is started, the counter should be notified using onFlowStart(). When a flow ends the counter should be notified using onFlowEnd().

Note that entering a flow node is not the same as starting the associated flow. For instance, if a flow node has a repeat expression which evaluates to zero, the flow node is entered and exited, but the associated flow is never started.

The global counter detects infinite flow recursion. The global count for a flow is incremented when a flow is started, and decremented when the flow ends.

The local counter detects infinite iterations. The local count for a flow node is incremented every time that node is reached and registered. The local counter is never decremented, however when entering a subflow the local counter enters a new, empty scope. Therefore, a flow node inside a repeated subflow will not cause a false-positive, as every time the subflow repeats, the flow node inside it is counted in a different scope.

Since:
11.1
Author:
Petru Galanton
  • Field Details

  • Constructor Details

    • FlowNodeCounter

      public FlowNodeCounter()
      Creates a new instance, with the system default maximum loop count.
    • FlowNodeCounter

      public FlowNodeCounter(int maxLoopCount)
      Creates a new instance with the specified maximum loop count.
      Parameters:
      maxLoopCount - the maximum loop count
  • Method Details

    • getMaxLoopCount

      public int getMaxLoopCount()
      Returns the maximum loop (and recursion) count. Exceeding this limit causes register(NodeID) to throw an InfiniteLoopException, and onFlowEnter(NodeID) to throw an InfiniteRecursionException.
      Returns:
      the maximum loop/recursion count.
    • register

      public int register(NodeID nodeId)
      Registers the current node reached in a flow execution in the local counter, increasing its count by one. If the count for the node with the given ID exceeds the maximum loop count an InfiniteLoopException is thrown.
      Parameters:
      nodeId - the ID of the current node in the flow execution
      Returns:
      the new local count for the current node
      Throws:
      InfiniteLoopException - if the local count for the current node exceeds the limit
    • onFlowEnter

      public int onFlowEnter(NodeID nodeId)
      Notifies this counter that a flow node was entered. The count for the current node is incremented in the global counter by one. If the count exceeds the limit an InfiniteRecursionException is thrown. NOTE: flow nodes must still be registered using register(NodeID).
      Parameters:
      nodeId - the ID of the current node (which should be a flow node)
      Returns:
      the new global count for the current node
      Throws:
      InfiniteRecursionException - if the global count for the current node exceeds the limit
    • onFlowExit

      public int onFlowExit(NodeID nodeId)
      Notifies this counter that a flow node was exited. The count for the current node is decremented in the global counter by one.
      Parameters:
      nodeId - the id of the current flow node, which should previously have been registered with onFlowEnter(NodeID).
      Returns:
      the new global count for the current node
    • onFlowStart

      public void onFlowStart()
      Notifies this counter that a flow associated with a flow node was started. Causes the local counter to start a new scope.
    • onFlowEnd

      public void onFlowEnd()
      Notifies this counter that a flow associated with a flow node has ended. Causes the local counter to revert to the previous scope.
    • getGlobalCount

      public int getGlobalCount(NodeID nodeId)
      Returns the global count for the node with the given id. If the node has never been registered in this counter, zero is returned.
      Parameters:
      nodeId - the id of a flow node
      Returns:
      the global count for the given node
    • getLocalCount

      public int getLocalCount(NodeID nodeId)
      Returns the local count for the node with the given id. If the node has never been registered in this counter, zero is returned.
      Parameters:
      nodeId - the id of a flow node
      Returns:
      the local count for the given node
    • getLocalCounterDepth

      public int getLocalCounterDepth()
      Returns the number of stacked local scopes.
      Returns:
      the number of stacked local scopes.
    • getLocalCounterSize

      public int getLocalCounterSize()
      Returns the number of nodes counted in the local counter in the current scope.
      Returns:
      the number of nodes counted in the local counter