-
Nathan Hertz authoredNathan Hertz authored
Capability Step Sequence Alternatives
Handling QA with two states, one for the DA and one for the AOD is an interesting conundrum for the capability step sequence. The naïve implementation concept we had fails to address a few aspects of it, namely that we may want user-defined state transitions, and also that we may want some capability definition-level control over when the steps are run and what happens afterward, since QA appears to be an operation that takes versions as input.
Mealy Machine Approach
An approach suggested by Mark Whitehead is to allow user-defined states and transitions. This can be implemented as a Mealy machine. In a Mealy machine, you have a set of states, inputs, and destination states. We augment this concept with the idea that we perform an action during a transition to another state. Suppose you have a machine like this:

We can represent this machine as a table:
Current State | Input | Action | Next State |
---|---|---|---|
Waiting for Approval | approval | start workflow | Executing |
Waiting for Approval | reject | notify user | Complete |
Executing | complete | notify DAs | Waiting for QA |
Waiting for QA | approval | notify AOD | Waiting for AOD |
Waiting for QA | retry | start workflow | Executing |
Waiting for AOD | accept | start QA-pass workflow | Complete |
Waiting for AOD | rejected | notify DAs | Waiting for QA |
In this design the step sequence is replaced by this table and some associated facts (what the start state is, at least). The states are completely defined by this table, and may pertain only to this particular capability (certain states, such as Complete, would have meaning throughout the system). Every input is a message receipt, so "input" needs to actually be a pattern, and what is obtained by the pattern match needs to be available to the Action, somehow. The system will have a finite set of actions, probably similar to the step sequences we have now (send notification, execute workflow). A user category could be permitted to force a request into a particular state, bypassing the actions.
There are plenty of questions that need to be answered here but this approach seems like a very human-friendly and flexible solution that is considerably more powerful than the step sequence without being especially dependent on third-party technology or greatly expanded parsing.
BPMN Approach
Another approach suggested by Mark Whitehead is to investigate BPMN and other business process systems, and see if we can create a pluggable architecture for that. I think this is interesting and we have a story to look into a prominent implementation in Python called "adhesive."
Python Steps
Another approach would be to replace the step sequence with a real programming language. It is possible to parse a piece of Python code from Python, and I have a prototype of a mechanical transformation from the natural syntax tree to a structure that can be paused and resumed at any point in the computation. This requires a CPS (continuation-passing style) transformation. The state of the step sequence is then embodied in the continuation object and its state. In this manner, when you execute a function that needs to wait, you simply return the message pattern you want to reactive this computation along with the continuation and local environment, and store these pieces in the database. Later on when you want to resume the computation, you match up the pattern to the continuation, retrieve it from the database and the state, and resume the computation.
This approach is extremely flexible and powerful, but will be difficult to understand, and would tend to leave the database in a state where it would be hard for humans to inspect it and understand where we are in executing a capability.