Stackless Page - mrietveld/jbpm GitHub Wiki
Home ▸ 1-Pager: Stackless
2015-04-08
"Stackless" refers to a refactoring of the jBPM workflow engine.
We currently have a "recursive" implementation of a process instance: the start node, calls the following node implementation, which calls the following node implementation, and so on and so forth. In this way, the process instance (between save points), builds up a "stack" of node instance methods which then all exit when the process instance reaches a save point.
A "stackless" implementation will loop through node instances and then execute each node instance. At the end of a node instance, the method will execute, so that no "stack" of node instance method calls will be built.
This refactoring is necessary in order to implement certain features of compensation. However, this refactoring will also prepare the jBPM workflow engine to be more distributable (run in parallel, swap state, etc.)
The overview jira issue for Compensation is JBPM-4349.
Move the workflow engine to a "Stackless" execution.
- "Stackless" execution model
- Possible backwards compatibility for logs
- Stackless/Queue refactoring
- Code
- Tests
- Backwards compatibility (logs)
- Documentation (configuration, behavior)
A process instance proceeds by calling the method(s) of the subsequent nodes. When a process instance reaches a point where the process instance must (temporarily or permanently) stop, the last call terminates, and the (java method) stack is cleared.
Compensation, however, has a number of semantics which make it unique with regards to other behaviors in BPMN2:
- trigger order
- "saved-state" logic (order of compensation handlers)
- other "meta" logic (transaction integrity, compensation handlers can be asynchronously executed)
In order to implement these, the first step is to refactor the core engine from a "stack-based" execution model to a "queue/loop" based model, where the following node is executed by retrieving it from a queue and executing the node. Execution of a node can lead to more nodes being added to the "node queue".
Kris's description:
The use of the Java stack for state is not ideal, I agree (as it imposes several limits), and could quite easily be changed I believe. Instead of immediately triggering the next node, we could use more something like micro-commands and add commands to a queue. The number of micro-command would be very limited I believe (trigger a node basically). I think it's also something we might have to do, to support something like asynchronous continuatiuons and transaction subprocesses.
"transaction subprocesses" refer to Business Transactions, which are a part of Compensation. "asynchronous continuations" are necessary in order to implement asynchronous Compensation Handlers.
2013-05-13
One of the problems with the migration from (java) invocation stack based to stackless, is that the behavior of a process instance will change. In particular, After Node Left (ANL) and After Node Triggered (ANT) events will be triggered at different times.
However, we'll mitigate this by letting users configure the engine in 2 ways:
- Old invocation based
- New command-queue based
The old way will keep the same behavior as the current implementation, while the new way will of course run node instances by looping through a queue of "node instance commands". The existing (drools) Action framework will be used for this.
June 1rst (related to 6.3.x code freeze).
- The "Stackless" refactoring is a big task, because we're intrinsically changing the structure of the engine.
- This branch is a decent start, but it's written for a stack impl, not a queue impl (ANT/ANL behavior). It does identify a lot of the points where changes will need to be made, though.
- QE/QA: keep QE/QA as up-to-date as possible to give them a jump on testing this
- Documentation: keep them aware of documentation developments (in community docs) so that they can gradually add them to the product docs