If a packet gets lost TCP will resend it, and will keep re-sending until it succeeds or the whole thing times out. You have probably seen this many times when you browse the web and a site does not load. So, if the connection breaks you will not actually know whether the server received something or not. You would have to start over and re-send. Therefore the server may receive duplicates which it has to deal with. This is similar to email where the server will remove duplicates if it receives multiple messages with the same id.
5xx would mean a server error, such as server run out of disk space.
In this particular case, none of these protocols (like MQTT, HTTP, SMTP, or whatever) is needed because they don't add anything to what TCP already does. But you would want to use a protocol anyway. You have learned how to use a protocol and now if you don't use it all your learning will be in vein. You simply must use it. That's how the bloat begins ...
Both ends know the connection broke though. The connection ends with IIRC a 2 way handshake FIN FIN or RST RST
Either way or others the TCP/IP stack will report it to the code. If you carefully wrap your own transactional code around that state machine, then there shouldn't be any dirty writes which can't just be rolled back.... thats if you care.
getHandler() {
mqttClient.publish("your ma!")
throw( Whoops )
}
And you would break that rule.
try{
// the whole shebang
// as the LAST failable thing
publish_stuff();
} catch {
// phew! "probably no mutation or emission"
} finally {
// The either or.
}
Is getting better. This is what tends to happen all the way down through the layers at each layer. None of them want to be "that layer!"
The "probably" comment though is another reason why the layers recursively check this pattern... or it's that one that doesn't.
Whatever "publish_stuff" does is being trusted to obey the pattern, "DO or Throw. Never both, never neither. OR"
The actual problem however is basically mooted in much the same way that "Parallel buses" was in almost everything.
Hard synchronous transactions have been overlaid with bisteringly fast async ones.... and return "notes". "I promise to pay the bearer of this request an answer. Sometime... at some point." If doesn't need to be an absolute record of truth, then it can be "eventually consistent". Lastest and best wins.
If you want a hard record of truth from such a system, you basically need to snapshot it at a moment of time and write it to an archive DB.
If you pay particular attention to your online banking statement every day for a few months, you will notice that even the international banking system is "Eventually consistent" and inconsistencies can exist in the "records" for quite a long time. In some cases 2 weeks. In cases of protest, years.
You see things like duplicate transactions where a "HOLD" on a card crossed in time and space with the "DEBIT" request. The system is out of sync. Invalid. But it gets corrected by an other process which detects and adjusts the ledger. No transactions are erased or even reordered, the ledger is adjusted append only to realign it. On your statement it can "appear" that they rewrote it by adjusting the balance in the past. Thats just an illusion formed by the query on the effective date rather than actual date.