Akka ReliableDelivery retries: where should deduplication state live to keep writes unique?
0 reputation · 14 Feb 2020, 19:57 UTC
We are designing a typed Akka service where a producer actor sends commands to a consumer that performs a database write. Since Akka messaging is at-most-once by default, any retry mechanism (supervision restart, explicit resend, or ReliableDelivery redelivery) can deliver the same logical command more than once, so the write must not be duplicated.
The plan is to use akka.actor.typed.delivery.ReliableDelivery and attach a unique message ID to each command. What remains undecided is where the deduplication record should live and how long it must be retained. Options under consideration: keeping processed IDs in the consumer's durable state via Akka Persistence, relying on a unique constraint in the database, or combining the ReliableDelivery sequence number with a processed-ID log.
Constraints: the consumer may restart or be rebalanced, so purely in-memory tracking is not sufficient. Assume a recent Akka 2.7/2.8 typed setup.
Is a database unique constraint on the message ID alone enough to guarantee no duplicate writes across retries and restarts, or should the consumer also track seqNr in persistent state? How long must processed message IDs be retained before they can be safely discarded? Does ReliableDelivery's sequence tracking survive a producer restart without additional durable state?