To run a flow chart, you schedule it for execution by adding it to the Flux engine.
When is a Flow Chart Considered "Running"?
Any flow chart that is scheduled, actively waiting on a condition, or executing an action is considered to be "running". Even if the flow chart is only waiting for a time condition before it starts executing some other action, the flow chart itself would be considered "running" as it has been scheduled and is active on the engine.
Put more simply, a flow chart is considered "running" once it has been exported to the Flux Engine – either using the Designer, using the "Start" button from the Operations Console, or using the APIs.
A flow chart is not considered running when it is simply saved to the file system or to the Repository. Even if a flow chart is saved to the Repository with a schedule, the flow chart will not actively run on that schedule until a user has started the flow chart.
When you export a flow chart to the engine, Flux follows these steps:
- Locate the first action or actions in the flow chart (any and all actions marked as a Start Action).
- If the first item is a trigger that must wait for a specific time, schedule the first firing of the trigger. If it is an action that can run immediately, begin running the action.
- Continue executing the flow chart as normal.
In short, to schedule a flow chart, you'll just need to start it (also called exporting). Flux will then handle all scheduling and execution of the flow chart internally from that point.
Adding Flow Charts to the Engine
Once a flow chart has been created as a FlowChart object, it can be added to the engine to be executed in the background. To add a flow chart to the engine, call Engine.put(). A fully qualified flow chart name will be returned, as shown below.
While the engine adds the flow chart, it also verifies the flow chart for correctness. For example, a Timer Trigger that does not contain either a time expression or a scheduled trigger date will fail verficiation. Consequently, the entire flow chart will fail verification, an exception will be thrown, and the flow chart will not be added to the engine.
Once the flow chart is successfully added, the unique flow chart name can be used to retrieve the flow chart from the database. Retrieved flow charts represent a snapshot of the flow chart in execution: while the flow chart on the engine will continue to execute, the retrieved flow chart will not. The flow chart name can be extracted from the retrieved flow chart by calling FlowChart.getName().
You can use the wildcard characters "" and "?" to search the namespace for flow charts. The "" character matches any character zero or more times, and the "?" character matches any character exactly once. Flux uses the JDK regular expression library to evaluate these wildcards.
Once started, a flow charts runs until it is finished. In general, a flow chart finishes when the engine executes a trigger or action and there is no appropriate flow to follow afterwards. There are some exceptions to this behavior: for example, a trigger or action may throw an exception, in which case the error flow is followed. If there is no error flow defined, there is no appropriate flow to follow and the flow charts finishes.
By default, the engine automatically deletes flow charts when they finish executing. In this way, Flux prevents the database from growing unbounded as new flow charts are added.
Adding Flow charts at a High Rate of Speed
Your application may call for adding many hundreds or thousands of new flow charts continuously. If this is the case, you can increase the throughput at which flow charts are added to the engine.
A single engine instance will only permit a certain amount of new flow charts to be added per second to the engine. If you need to increase that throughput rate, you can instantiate a second engine instance and add additional flow charts through that second instance.
Both engine instances will add new flow charts to the same database. Consequently, these newly added flow charts will be eligible for firing by any engine instance in the cluster.
In fact, you can create a number of engine instances and use them in parallel to add new flow charts to the engine. This "array of engine instances" can be used to add new flow charts at a high rate of speed.
To configure the array of engine instances, follow these steps.
- Create an appropriate number of engine instances for the array. The right size of your array depends on the sophistication of your computer system, but as a rule of thumb, create between 2 and 8 engine instances. You may need to adjust the size of your engine array to match the capabilities of your computer system. An engine array that is too large will slow down your system.
- Configure each engine instance to point to the same set of database tables.
- Do not start any of the engine instances. A started engine will not add new flow charts as fast as a stopped engine. By default, a newly created engine instance is stopped, and is only started by calling Engine.start().
- (Optional) Disable cluster networking on each engine in the array to increase throughput by a small amount.
Use the array of engine instances to add new flow charts. You may need one or more additional engine instances to actually fire flow charts. These other engine instances must be started in order to execute flow charts.
Flow Chart Order of Execution
When multiple flow charts are waiting to be executed on an engine, the engine must determine which flow chart should be executed next. To make this decision, the engine considers three primary factors: Eligible Execution Time, Priority, and First-In-First-Out Scheduling.
- Eligible Execution Time
Eligible Execution Time is the time at which a flow chart declares that it is ready to execute. Most actions are ready to execute immediately once flow chart control reaches them. Most triggers, on the other hand, wait until a certain time before they are ready to execute, at which time they check to see if a condition particular to that trigger is satisfied.
Note that a flow chart may not actually fire at its Eligible Execution Time due to engine availability or scheduling conflicts. Moreover, if a flow chart is paused, it will not execute, regardless of its Eligible Execution Time.
If two flow charts are both ready to execute -- that is, the wall clock (the current time) is at or beyond their Eligible Execution Times -- the flow chart with the higher priority will always run first. Flow chart priorities can be set directly on a flow chart or through the runtime configuration. The lower the number, the higher the priority; a priority of 10 takes precedence over a priority of 100. For more information, see Runtime Configuration.
- First-In-First-Out (FIFO) Scheduling
If enabled, FIFO Scheduling controls whether flows charts are scheduled for execution in a first-in-first-out manner. When a flow chart is originally submitted to an engine, the current timestamp is recorded as the flow chart creation timestamp. Next, when a flow chart's Eligible Execution Time permits it to execute, all such eligible flow charts begin execution in the order of their creation timestamps. Priorities take precedence over FIFO scheduling; if an older and a newer flow chart are eligible to execute and the newer flow chart has a higher priority, the newer flow chart begins executing first.
Other factors may also affect the order of execution. For instance, the fairness time window, if enabled, can temporarily raise the priority of starving low priority of flow charts.
Concurrency throttling can also affect the order of execution for your flow charts. Concurrency throttling takes precedence over Eligible Execution Time and Priority. A concurrency throttle might only allow a certain number of high-priority jobs to execute at once, which could cause some low-priority jobs to be executed instead (An example of this is demonstrated in (#Concurrency Throttle below). For more information on concurrency and the fairness time window, refer to Runtime Configuration .
Order of Execution Examples
Eligible Execution Time and Priority
Group A contains 15 flow charts that each take 1 minute to execute. All of the flow charts in Group A are submitted at 8:00. The flow charts in Group A have a priority of 300.
Group B contains 10 flow charts that each take 2 minutes to execute. All of the flow charts in Group B are submitted at 8:05 and have a priority of 100.
The flow charts in both groups are ready and scheduled for immediate execution. The concurrency throttle is set to 1, meaning only 1 flow chart may execute at a given time.
At 8:00, Group A would have preference and begin executing. At 8:05, 5 flow charts from Group A have already been executed when Group B is submitted to the engine.
Now, both groups are scheduled for immediate execution, since the wall clock (the current time) has advanced beyond the Eligible Execution Time for both groups. Consequently, either group may execute next, but because Group B has a higher priority, Group B's flow charts begin executing, since its priority is higher than Group A's.
Once all 10 of Group B's flow charts have run to completion, the remaining 10 flow charts from Group A will execute.
Flow Chart Creation Timestamps
Group A and Group B both contain 10 flow charts that take 1 minute to execute. The flow charts in both groups have a priority of 300, and the concurrency throttle is set to 1.
Group A's flow charts are submitted to the engine at 8:00 and therefore have an Eligible Execution Time of 8:00. Group B's flow charts are submitted at 8:05 and therefore have an Eligible Execution Time of 8:05.
At 8:00, Group A would have preference and begin executing. At 8:05, Group B's flow charts are submitted to the engine.
This time, precedence goes to the flow charts with earlier Eligible Execution Times. In this case, because Group A was submitted at 8:00. The remaining 5 flow charts from Group A must finish executing before any flow charts in Group B will run.
Group A contains two flow charts, each of which takes 10 minutes to complete. These flow charts have a priority of 100, with a concurrency throttle of 1 on this branch in the flow chart namespace. This means that only 1 flow chart from Group A may execute at a given time.
Group B contains three flow charts that each take 1 minute to complete. These flow charts have a priority of 300, with a concurrency throttle of 1 on this branch of the flow chart namespace.
Both groups of flow charts are submitted at 8:00. The concurrency throttle on the root node of this flow chart namespace is set to 2, meaning that only 2 flow charts can execute at the same time.
At 8:00, the first flow chart from Group A and the first flow chart from Group B will begin executing simultaneously. This is the effect of concurrency throttling: while 2 flow charts are allowed to run simultaneously, each group is throttled so that only 1 flow chart can execute from that group.
Because concurrency throttling will not allow the second flow chart from Group A to execute while the first is still running, all three flow charts from Group B will finish before the second flow chart from Group A runs, even though Group A's flow charts would normally have preference due to their priority.
Group A and Group B both contain two flow charts that execute for a minute, wait at a trigger for two minutes, and then finish executing for one more minute. The flow charts in both groups have the same priority, and the concurrency throttle is set to 1.
Group A's flow charts are submitted to the engine at 8:00 and therefore have a Flow Chart Creation Timestamp of 8:00. Group B's flow charts are submitted at 8:01 and therefore have a Flow Chart Creation Timestamp of 8:01.
At 8:00, Group A would have preference and begin executing. At 8:01, Group B's flow charts are submitted to the engine.
This time, precedence goes to the flow charts with earlier Flow Chart Creation Times, and a flow chart in Group A begins executing. At 8:01, the second flow chart in Group A executes. At 8:02, the first flow chart in Group B can execute since both flow charts in Group A are waiting at their triggers. At 8:03, a flow chart in Group A as well as Group B is eligible to run. However, since the Group A flow charts have older flow chart creation timestamps, a Group A flow chart must run next.
This FIFO Scheduling scenario shows that among those flow charts that have Eligible Execution Times at or beyond the wall clock time (the current time), they begin executing according to the order of their flow chart creation timestamps. If the concurrency throttle is 1, they execute in a true queue-like manner. If the concurrency throttle is more than 1, they begin executing in FIFO order, but the first flow chart may not finish before a successive flow chart starts. Finally, a flow chart that begins executing and reaches a trigger must wait until the flow chart's Eligible Execution Time once again reaches the wall clock time, at which time that flow chart is subject to FIFO Scheduling once again.
Flow Chart Execution in a Clustered Environment
Flux uses a Master/Worker architecture to assign flow charts in a clustered Flux environment. The "Master" engine of the cluster is assigned based on the creation sequence of the engines. The first engine to be created in the cluster will be master. If that engine was to dispose, or shutdown unexpectedly, the subsequent engine created would then take on the master engine's responsibilities of assigning flow charts to run. Flux uses RMI to network each engine together, sharing relevant information. If RMI is disabled on the network, or for some reason the engines can not communicate with each other, each engine then essentially becomes a master engine.
Flow Chart Distribution
When the master engine deems a flow chart is ready for execution, the worker engines are then analyzed to determine the best engine on which to execute the flow chart. There are three possible algorithms that are used depending upon your environment and configuration:
- Greedy: If the engines are unable to communicate with each other for whatever reason, each engine becomes a master engine and a Greedy algorithm is used. Whichever engine first retrieves, claims, and ultimately is allowed to run the flow chart, executes it.
- Load Balancing: If the engines are able to communicate with each other, but the System Resource Monitor is not configured on all the engines in the cluster, a load balancing algorithm is used. This algorithm looks at how many flow charts each engine is currently executing and deems the engine with the lowest count the primary engine for execution of the selected flow chart. If, for some reason, that engine is unable to execute the flow chart, the next best engine attempts to execute it.
- CPU Load Balancing: If the engines are able to communicate with each other, and the System Resource Monitor is configured on each engine in the cluster, a CPU load balancing algorithm is used. This algorithm analyzes each engine's CPU usage and deems the engine with the lowest CPU usage the primary engine for execution of the flow chart. If that engine is unable to execute the given flow chart, the next engine with the lowest CPU usage attempts to execute it.