In previous installments of the series I have described the relatedness between Conway’s Law and popular software architectures, and then described what a typical Mainframe architectured organization might look like.
Now let’s look at Client-Server architecture, and some of its characteristics.
There are various interpretations of a client-server system, and there is a great deal to learn about an organization from the way servers and clients interact with one another. I am describing here four possible architectures, and what we might learn from them.
In the image, on the top-left there is a single server system, and clients are configured to “talk” to the server. If you recall the earlier Windows file servers, they were much like this. In order to get connected to a server, the client had to “know” the details of its server. Once defined, the client would “ask” the server for data, and the server would “answer” with a result – either “here is your data” or some “I don’t know” response.
In organizational terms, this resembles the familiar hierarchical model. each employee has a manager, and the manager “tells” the employee what he or she should do, and “answers” whatever the employee “asks”. What’s nice about this system is that it’s simple. Its downsides are, clearly, that it is error-prone (what do I do when my manager/server is not present?) and that clients must have all their data (or at least data of a given type) with one server or manager.
At the bottom left we have the next evolution of the same model. Here we have the master, and next to it the slave or backup or warm-backup. What we’d call in organizational terms a deputy or acting-manager. Under normal operation the primary server, or the master, is active, and when the master is down, the slave kicks-in. The nice thing about it is that it’s still fairly simple. The downside? It’s pretty much the same as before, with just a little more availability and much more complexity in synchronizing the two.
In organizations this means that for the client the decision is seemingly pretty simple – when the manager is not present, talk to the acting-manager. In reality, this is still a highly hierarchical model, with the expectation that managers and their deputies will always be in full synchronization. And just like in servers where an instant, 100% of the time, full synchronization is extremely hard, so are managers finding it too hard to be in full sync. In fact, since humans are much more complex than computers, this expectation is impossible to achieve.
On the top right we see two masters, both active at the same time. They are not master and slave, rather they are ‘A’ and ‘B’ to denote that each has a different (although likely overlapping) subset. In software terms these could be the print server and the file server, or the employees DB server and the salaries DB server, or they could both hold all the data, and sync between them to have the most-up-to-date subset.
The arrows, representing the configuration of the client to talk to a specific server, are replaced with the aerials: each server is “announcing” (broadcasting) what subset it holds, and clients “listen” to announcements to decide which server they need/can connect to. This is a more complex model, for many reasons:
- Servers need to synchronize constantly
- Servers, unless there is no traffic, are never 100% in sync
- Clients should decide, based on some policy, which server to connect to. For example, to the server with the lowest latency (==distance)
- Clients and servers should validate if their data is correct, and perform a recovery procedure to reconcile discrepancies
This model, although more complex, is much more loyal to real life than the previous models. For starters, it assumes that clients (employees) are responsible for connecting to the right server, and to make decisions based on changing reality.
I’ll reiterate this: employees are responsible for making decisions on who is the right manager for completing a given task. This, by definition, is quite different to the standard, hierarchical, model.
It goes without saying that it is harder to implement such a model. It requires more synchronization, to work in a transactional model, it requires to announce frequently what I know and what I don’t know (or don’t possess).
In agile terms, it requires to plan continuously, and not periodically, and to implement responding-to-change mechanisms. It also requires to retrospect frequently and regularly to consolidate discrepancies.
At the bottom right of the diagram there is a cluster of servers, each broadcasting in some internal group, or cloud, and the cloud itself is broadcasting its aggregate status. Ultimately, when a client connects to the “cloud” it will talk to a specific server and will remain with the same server for as long as it makes sense (for example, if it’s a fully stateless system, then nodes can change with every interaction; and if the server keeps a state, then clients will “talk” to the same node until the state hops to another node, or the transaction are complete, or the node has dropped).
In organizations this means that a specific employee does not need a direct manager to do his or her job. Yes, managers are needed, and yes, management functions are performed. But for the employee it becomes (almost) transparent which manager he or she is talking to.
This implies that managers must work as a team, with mechanisms we expect work-teams to perform, such as daily stand-ups, task hand-offs when needed, visibility tools, transparency, and improvement stops at a frequent cadence.
A traditional Client-Server architecture implies a hierarchical structure. This implies that the opposite is also true: If you have a highly hierarchical organizational structure, your chances of developing a product that resembles the bottom right kind of architecture are not high.
Here is a simple example of why this is true. This is just one of many reasons:
- If team A is developing the front-end, and team B is developing the back-end, and each team has a different manager (server), then they are working on foreign data sets. In order for them to accomplish a working cloud-like system, then managers need to act as go-betweens to solve their problems. The number of communication combinations goes exponentially up as team sizes grow, making it impossible for managers to accomplish this.
- If, on the other hand, employee A in the front-end team is working on a feature requiring a task from employee B in the back-end team, and employee A has the freedom to approach the other teams and managers, then the manager is free from making decisions on the employee’s behalf.
- Moreover, if employee A is free to team-up with employee B, and form their own team for making features, without the “server’s permission”, the organization becomes more elastic.
In other words, if your organization is elastic, it can scale up to build complex solutions. However, if your organization is rigid, it will fall short of building truly elastic and scaling solutions.
That is not to say that a hierarchical structure is not good or unwise or anything of the sort.
And coming back to the premise of the original post in the series, if you find that you fail to deliver the elastic and scalable software solution that you desire, it may be a good time to take a look the organizational structure, and see if your hierarchy is blocking you from the elasticity you need in your organization to achieve your goals.