Evolution as a primitive
Everybody can and will create systems that does the first thing. (Usually (println "Hello World")
)
We will make a system where evolution is the building block or the primitive. Evolution just means observing many cycles of life, each generation a little bit different from, but also related to, the generation before.
Before we look at that, we have to establish the smallest detectable cycle; that of waking state and non-waking state. Both are forms of living, but the are separated by the ability of This to perform utility.
Before any process can execute it needs to locate and hold on to external resources. Eg databases, secrets, ports & files. (That) Once this is holding onto that, all the conditions for utility is present and work may happen.
An environment may also change unexpectedly. ie That can change unexpectedly. In such cases the system may stop working temporarily (becomes unconscious) while the conditions for utility are restored (by an outside agent).
Basic Life cycle (unit)
We can simplify evolution a lot by looking at it as if all processes follow an ordered life cycle.
What does this give you?
Compose-ability.
There exists natural relay points when all the players in the system follow the same cycle. Observe how the previous version of the system's "dead" state corresponds nicely with the "ready-to-start" state of the next iteration of the system.
But, what happens while both systems are unconscious?
No system exists in isolation. All forms of life are interconnected.
In the simplistic answer to this question just observe the effects of having a plurality (many instances) of the same (form of) life. You don't have to upgrade all of your system instances at once. You may stagger upgrades so availability is maintained consistently throughout the process.
As an alternative strategy, keep in mind that you may also build systems that facilitate the transition between generations of creatures. The strategy that is chosen depends on things specific to the nature of the work that is being performed and are not generalisable.
This leads us to the first Design Principle:
Don't interfere with other forms of life
a.k.a. Don't move the cheese!
- If you are creating the next version of a system, don't mandate that all other versions and previous generations of your app must be killed before you are allowed to start. If possible, intelligently facilitate the handover or let another agent facilitate this for you.
- Keep this in mind when making changes to
configuration
. Don't change the meaning of configuration. Don't let two versions (simultaneously alive) have conflicting ideas about what a piece of data means. Instead, add new pieces of configuration and deprecate old pieces of information. When something has been deprecated and has fallen into dis-use, then clean it up in a manual way.