When communication is reestablished, that issue can be sorted out. See "two-phase commit".
When communication is reestablished, that issue can be sorted out. See "two-phase commit".
Which is it?
Such as, e.g. a remote mail server if the operation was to send mail to take an obvious one.
In other words: The server does not need to go permanently offline - it may be sufficient for the established session to terminate.
An easy way to think about solving the exactly-once problem, on top of an at-least-once message layer, is to use the at-least-once layer to write idempotently (eg, HTTP PUT) into a sequence of numbered messages.
There is no possibility that the receiver will execute message 18 before message 17. Each PUT retries until an acknowledgment is received, and the sender maintains a sliding window of sequence numbers it's trying to write.
All the Two Generals problem tells you, in this situation, is that the sender does not know whether the receiver got the last message. It's an important issue and I agree with the general sentiment of the OP, but perhaps it can be overstated.
* Perform the action, then acknowledge the message.
or
* Acknowledge the message and then perform the action.
(assuming delivery of messages is reliable)
In either case, if they crash after the first part, it will either be carried out twice, or not at all. When/if communication is established again, you need to ensure that the node is A. able to gurantee that it knows if an action was carried out or not, B. able to undo an action if the coordinator decided to send it elsewhere.
This is not always possible, and you cannot have a message system that gurantee exactly-once, without the recieving system supporting it.