One of the first articles posted to SIP Sessions discussed Postel’s Maxim, also known as the Robustness Principle:
Be conservative in what you do, be liberal in what you accept from others.
That article gave examples of how robustness declines when individual implementations don’t follow that principle. Today, I’d like to explore how the principle helps large systems and architectural design.
Imagine a system where all of the elements present are following this principle. Then introduce a single new element that doesn’t.
- An element not following the first part of the principle will not be careful with what it emits. It might emit things that force edge conditions to occur, or even outright violate the protocols the system is using. The system as a whole will continue to behave robustly. Being liberal in what they receive, the remaining elements will forgive as much protocol violation as they can without emitting non-conformant messages themselves. They will have anticipated gracefully handling edge conditions. The system as a whole will not be significantly perturbed by the new element, and for the most part, the new element is likely to get whatever services it wanted.
- An element not following the second part of the principle will be over-sensitive to variations in the messages from others. In the perfect system discussed so far, all the other elements are being careful to send conforming messages, so the new element’s brittleness won’t be exposed. The system continues to work robustly, at least until the rest of the system starts to evolve.
Now take the same system and introduce a very large number (enough to be a majority) of new elements that don’t follow this principle.
- If the new elements are not conservative in what they emit, the entire system is placed under strain. The previous elements are now executing exception code as part of normal operation. Edge cases become the norm for them. The system no longer meets the expectations used to make optimization decisions in the original elements. In many cases, however, the system still won’t fail. But the robustness has been removed – used up. The next wave of non-conformance has a much higher chance of bringing the system down.
- If the new elements are overly sensitive to what they receive, the strain is not (initially) so great. Because the original elements are conservative, this sensitivity isn’t exercised and the system will seem unperturbed. But then someone will have a bright idea and introduce a new, standard behavior into the system. These new elements, and remember they are the majority, will not accept this new behavior. A forklift upgrade of all of them will be required before a single new element trying to exercise this new behavior can be expected to work.
In short, a system that takes advantage of the robustness principle can survive even a large number of ill-behaved participants, but the cost is becoming brittle.
It’s easy to overlook this resulting brittleness when trying to solve any particular problem in isolation. It might be tempting to say – “Well, it’s ok if we violate this part of the specification, because this other part of the specification says conformant elements must not break if we behave this way.” This is a trap. It’s like saying “I can speed through every intersection, even if the lights are red, because the law says other drivers are required to make sure the intersection is safe to enter before doing so.” It’s even worse for a specification or an operational policy to encourage violating half of the robustness principle this way. That’s like having a driving school telling its students to run through all the red lights.
Hey, it would work if the rest of the system were perfect in executing the “make sure the intersection is safe” rule.
That’s where reality tears the notion down. The system I had you imagine at the beginning of the two exercises above cannot exist
in the real world. Real systems will have imperfections. Systems that use the robustness principle make it less likely that those imperfections will result in failure. Introducing elements that don’t follow the principle negates that robustness, and in real systems, will cause those systems to fail.