4 ms·
I completely agree that pragmatism is essential to being a great developer. When designing a system, you should be asking yourself questions like: 1) What sort
by a-priori 13y ago
I completely agree that pragmatism is essential to being a great developer. When designing a system, you should be asking yourself questions like:
1) What sort of load will this system need to handle now and in the foreseeable future, and what sort of latency can it tolerate? How will that load flow through the system? In this contrived scenario, the server and database need to be able to handle an average throughput ~9 requests a minute with lax latency requirements (it's okay if things are backed up by a couple minutes). The devices only need to handle one operation per hour. Planning a safety margin of perhaps 10-100% above that is prudent; more than that is premature.
2) What are the upgrade characteristics of each component: how will you upgrade or replace each component? how long would it take? can you even upgrade them? Some parts will be in a central location, and can be easily upgraded with only minor downtime. Some will be deployed on hardware you don't control or otherwise can't be easily upgraded. In the worst case, they're embedded in firmware and you need to support them as-is for their entire lifespan.
3) What are the failure modes of each component: what could cause them to fail? how likely is that? what will happen if (when) they do? how will you recover?
The answers to those questions determine how much risk you can take when designing each component.
Also, look at where the answers are different for two components that talk to each other. Any time there's a boundary between two components that can't be upgraded at the same time, or where one component talks to another with different failure modes, there's an interface. You need to think hard about the interface between them: how will they communicate? how will you extend that communication protocol over time while maintaining backwards compatibility? how will they behave if the other has failed? Those interfaces are locations where over-engineering a bit can pay off.
So for this example, I would think hard about what runs on the devices and how they talk to the back end, because that code is probably very difficult to upgrade. I would use rock-solid, dependable technologies for those. Similarly, the database probably stores important information, and one of its failure modes is that all the data is lost due to hardware failure. So I would use a mature database there, either MySQL or PostgreSQL.
But the back-end service? It's easy to upgrade and because it's stateless, its two failure modes are that it crashes and it needs to be restarted, or that the hardware fails and it needs to be re-deployed. Neither failure mode is that bothersome, so it doesn't matter what technology you use there. Use whatever the team is most familiar with and will let you iterate the fastest.