|
Command and control
Using atomic, cohesive code opens up the possibility of using declarative state machines. Declarative state machines have been around for a while; they allow you to design flows of steps in a declarative way, often in XML or some other domain-specific language (DSLs). They are often used in middleware and in defining business logic and workflows. Spring Web Flow is based on this concept, as is Microsoft Windows Workflow, and Appistry's own Process Flow technology. There are many other examples.
Typically, the model runs something like this: a state machine of different steps is defined. Each step or state is tied to a task or unit of executable logic. The state to which the machine branches is determined by the task execution results of the prior step. If a step succeeds, then the next step takes some happy path. If a step fails, then the next step may execute a compensating task to deal with the failure, or request help, or return failure. Success or failure is usually defined by conditional logic, rules, data values, thrown exceptions, and other conditions.
By using declarative state machines to orchestrate atomic, stateless, and perhaps idempotent code in the context of distributed environments like cloud platforms, you can get surprising levels of robustness, reliability, and flexibility. Additionally, if your code must be stateful or cannot be safely re-executed because its operations are not idempotent, the declarative state machine makes that code more reliable. The declarative nature of the state machine allows your design to accommodate failures in these conditions, without putting the failure handling inside your code. Also, some state machines allow for snapshooting progress in the state machine steps, so that a process interrupted by failure can be resumed and completed. Again, this is something that would not be possible without making sure the code breaks down nicely into atomic steps or tasks.
When this technology is seen in cloud platforms, it allows the orchestration of your code across many workers in a reliable, scalable, available, and load-balanced way without your code knowing about it. |
|