The performance of network applications can be measured not only by the speed at which they resolve requests, but also by their ability to recover from faults outside of a reasonable scale of culpability. What if the hardware is power cycled during a long running operation, or a network outage causes the pending job handler to throw unreachability errors?
Graceful recovery can often be tricky to engineer and test, and in some cases can be detrimental to performance under stable conditions. Here are some examples of conditions that a Host might need to consider when rendering and returning a payload to the Gateway when a local network outage occurs:
- I'm midway through rendering. Should I continue?
- I've rendered and have a payload. Should I try and send it anyway?
- I can't see if my software is up-to-date. Should I presume it is?
- I can't see my current assigned Gateway. Does it have the same IP?
These examples of granular state conditions become perpetually more unmanageable as application complexity progresses. However if we approach the fundamental application operations and treat them as singularities, we suppress any notion of controlled recovery in favour of a fail fast approach. Stateful tasks become contextually transient, failure is fatal, and recovery is more like rebirth.
To explain how we achieve this, let's start with an example:
Pump and tank
In this example application we have a pump and a tank. The tank must be open for the pump to work, and the pump must be stopped when the tank is full.
Main
func main() {
// Create a new tank and pump
tank := new(Tank)
pump := new(Pump)
// If the tank opened successfully, pump the water
Knowledge
Last Updated:
March 2020