Here is a crazy idea: imagine an information technology (IT) solution where the only persistent memory is write-once, read-many (WORM), or a database without update and delete commands. This book claims such immutable data stores form the basis of a better future, solving some hard and recurrent problems. Blockchain solutions provide some evidence that it is not that crazy.
The book proceeds in three parts: definition of immutable architecture, application of the theory, and implementation.
Part 1 starts with why immutable architecture is relevant. Common and hard problems in distributed systems are caused by the unreliability of connectivity and components. The two-general problem clarifies the fundamental problem of achieving consistency in the face of such unreliability. The approach in this book is to “model the business domain as one large immutable data structure.” As computer systems are built on, and deal with, change all the time, it seems outrageous.
A core idea is structure sharing, explained with inserting a node in a tree: the old and the new tree share parts of the tree. The old still exists as before, unchanged; the new only contains new nodes for the changed path. Two key phrases capture the main idea: “immutable records are observed state, objects represent derived state” and “derived state appears as a ‘view model.’”
Three styles of immutable architecture are discussed: event sourcing, asynchronous model view update, and historical modeling. In event sourcing, changes are caused by events, themselves immutable, and the current object state is derived from this source only. Asynchronous model view update is a derivation of model-view-controller incorporating immutable state on both the client and server sides.
Historical modeling uses immutable facts that are partially ordered in a graph based on predecessors. These graphs are immutable, too. This style is the focus of this book. It sets some limitations: no central authority, no real-time clock, no uniqueness constraints, and no aggregation. The last chapter in this part presents a textual and graphical representation for historic models.
Part 2 looks at applying the model. A golden principle is to ensure location independent representations. The author explains, in a simple and clear way, all problems related to location dependence, especially for the identity of an object. The author promises a solid math basis for his work, and the next example is the CAP theorem: you can only have two of (strong) consistency, availability, and partition tolerance. It prevents looking for an impossible solution and refocuses on strong eventual consistency (SEC), which allows for all three. SEC can be achieved if the receiver of messages attains the same state if a message is received twice, or if the messages would be received in a different order.
The next element is a mouthful: state-based conflict-free replicated data types. This is a general solution to obtain SEC. The chapter ends with some examples that make it easier to digest the presented contents.
The chapter on analysis provides examples of techniques to be used during analysis, featuring atomic decisions, prerequisites, dealing with identifiers, the cardinality of relations, views, and wireframes. Regions of the diagram for the various actors provide a swim-lane-like aggregation with cross-lane links clearly exposed. That first part of the analysis provides guidance for the modeling.
The next part discusses how to use the model: publishing facts, integrating subsystems, race condition elimination, constraints, navigation, and searching.
State changes. The immutable architecture must provide solutions for this reality. It starts with finite state machines and state diagrams, observes the danger of explosion of states, and provides functions to declaratively determine state changes as a remedy. It then proceeds to combine state transitions with the historical model, with examples and pseudocode to address the issues.
The security part discusses authorization and access control in a distributed environment with delegation. In an immutable approach, authorization revocations are unavoidable. The other security topic is providing data confidentiality. It is a nice illustration of how to tackle even security.
The chapter on patterns provides a basic set to get a head start and includes patterns for entity, ownership, delete, restore, membership, mutable property, entity reference, transaction, queue, period, and outbox. For each pattern it provides the motivation, the structure, an example, its consequences, and related patterns.
Part 3 is “Implementation.” The first topic is query inversion, something requiring a bit of explanation. The author considers a graphical user interface (GUI) as a cache of “query results, stored in view models and browser DOMs.” The question is when to invalidate this date. The answer is via (automated!) query inverses.
The invalidation of the “cache” is caused by new facts. The query that produced the initial cache content is the key to understanding on which facts the results depend. Inverting the query process tells if the cache is impacted by any new fact. This inverse query construction can be automated using these elements: new facts cannot impact successors; all views (data caches) start from a specific point in the data graph. The rest of this chapter deepens the topic: optimizations and more complex and nested query inverses. Fortunately, the author makes a query inversion implementation available.
The chapter on SQL databases demonstrates how relational databases can be used in line with the requirements of an immutable architecture. It looks at restrictions and techniques for common issues. Content-addressed storage is a key element. How to deal with the performance impact of the “not exists” core function is a practical concern.
In the chapter on communication, the author gets back to one of the motivations of an immutable architecture: unreliable communication. Typically, communication choices and processing are tightly bound, whereas the immutable architecture provides separation of concerns. The author covers themes like reliable delivery, message processing, and data synchronization.
The last chapter starts with a discussion of how to present views on the immutable data, specifically projection and interest: users are offered a projection of the dataset, and user interfaces have specific interests in (new) facts.
The book concludes with a sketch of a bright future based on immutable architectures. Whether that will be the case remains to be seen. One thing is clear: immutable architecture is something to watch and learn from, and the author succeeds in presenting it very well.
More reviews about this item: Amazon