Come implementare la semantica della serializzabilità in un sistema alla fine coerente?

2

In un sistema asincrono distribuito, la serializzabilità non può essere raggiunta, ma dobbiamo ancora fornire in qualche modo la semantica.

Considerare il requisito del tutto naturale che l'utente debba avere un'e-mail univoca o nessuna e-mail. (L'opzione di non avere un'e-mail implica che non possiamo usare l'e-mail come indirizzo di un attore unico.)

Cosa dovrebbe accadere quando il sistema riceve due richieste simultanee per la creazione di un utente con la stessa email? Uno di loro alla fine dovrebbe fallire.

Potremmo interrogare tutti gli attori degli utenti chiedendo se qualcuno ha la stessa email, ma a causa della concorrenza nessuno dei due nuovi utenti potrebbe essere creato in quel momento. Lo stesso problema esiste per l'aggiornamento della posta elettronica.

Come ottenere queste funzionalità senza compromettere scalabilità e prestazioni? Come faccio a lasciare che il client ora che la sua richiesta non è riuscita?

    
posta Pavel Voronin 26.09.2018 - 12:40
fonte

2 risposte

2

L'approccio più diretto è probabilmente quello di distinguere le e-mail verificate da e-mail non verificate all'interno del modello e di avere un singolo attore responsabile della verifica di un determinato indirizzo e-mail.

(Le versioni semplici sono che hai un attore responsabile della verifica di tutti gli indirizzi email o di un attore responsabile della verifica di ciascun indirizzo email.)

Questo ti dà la creazione parallela di utenti, ma l'ordinamento seriale dei messaggi che i due attori degli utenti inviano alla casella di posta degli attori di verifica email.

(L'e-mail è inoltre complicata dal fatto che l'applicazione non è il libro dei record per gli indirizzi e-mail dei tuoi clienti, in teoria un indirizzo e-mail potrebbe essere riassegnato senza che nessuno ti dica che è successo.)

    
risposta data 26.09.2018 - 13:43
fonte
1

Questo è noto come set validation .

Ad un certo punto nel tempo, prima o poi, dovrai serializzare questo controllo, quindi la scalabilità ne risentirà sicuramente. Puoi ancora scegliere quando: prima di creare l'utente o dopo.

  1. Prima che l'utente venga creato

Per questo puoi avere una collezione in un database con un indice univoco sull'indirizzo email. Se l'inserimento ha esito positivo, l'utente è il primo con quell'indirizzo email e sarà consentito, altrimenti il comando verrà rifiutato.

Lo svantaggio è che la creazione dell'utente potrebbe fallire per altri motivi e che l'indirizzo email rimarrà utilizzato da un utente inesistente. Per questo puoi avere una Saga che pulisce quegli indirizzi email orfani.

Il modo più pulito sarebbe quello di fare questo inserimento / controllo quando viene cliccato il link di verifica dell'e-mail.

  1. Dopo che l'utente è stato creato , verifichi in seguito gli indirizzi email duplicati con una Saga. Se c'è solo un'istanza della Saga, puoi essere certo che rileverà indirizzi email duplicati; se ci sono più istanze, avrai bisogno di una collezione con un indice univoco, proprio come sopra.

How do I let client now that its request failed?

Non puoi mandargli una email perché l'email è usata come un altro utente. Puoi inviarlo notifiche basate sull'ID di sessione, purché abbia la stessa sessione, o quando effettui l'accesso la prossima volta (se hai un'altra media di autenticazione).

    
risposta data 26.09.2018 - 20:50
fonte