If I have a service that consumes events of type A and emits events of type B, how can I make sure that event B is only emitted once for every event A?
L'unico modo per farlo è quello di garantire che tutti i consumatori dell'evento B facciano parte della stessa transazione dell'evento A.
In un mondo distribuito? nessuna possibilità.
Al massimo una volta che la consegna è banale, è sufficiente inghiottire l'evento B senza mai emetterlo.
Almeno una volta che la consegna è gestibile.
Esattamente una volta che la consegna è al di là economicamente praticabile.
Nella maggior parte dei casi, i punti importanti sono (a) fare il massimo sforzo per garantire che i consumatori riconoscano gli eventi che sono stati elaborati con successo e (b) per avere protocolli in atto per gestire le circostanze quando gli eventi sono stati elaborati più di una volta.
(Esempio: sugli aerei, siamo legalmente limitati a un passeggero per posto, ma a volte può accadere che due passeggeri siano assegnati allo stesso posto. Anche in questa crisi, l'aereo di solito riesce a raggiungere la sua destinazione ... .)
With just at least once delivery, it seems like this would cause an amplification of duplicate messages?
Certamente potrebbe - penso che dipenda da cosa seguono i punti di sincronizzazione e quali strategie vengono applicate dai gestori quando riconoscono un messaggio duplicato.
Ad esempio, se un destinatario sta elaborando messaggi in batch, potrebbe ricevere due copie di un messaggio e riconoscerne la duplicazione.
D'altra parte, il messaggio duplicato può essere un'indicazione che un riconoscimento è stato perso durante il transito, nel qual caso il riconoscimento dovrebbe essere rispedito, in modo che il partecipante a monte possa sapere che il requisito almeno una volta è stato rispettato .
Un buon punto di partenza per questo genere di cose è Messaggistica affidabile senza transazioni distribuite di Udi Dahan. Puoi riconoscere alcune somiglianze con il Pat Helland articolo a cui fa riferimento Constantin