Assumiamo questo scenario concettuale:
Il database viene costantemente popolato con "una tonnellata" di attività denominate PleaseSendAnEmail
.
Uno scheduler / listener in background ha lo scopo di gestire tali compiti.
Naturalmente, le regole sono che una mail specifica non dovrebbe essere inviata più di una volta e che la gestione dovrebbe essere la più veloce possibile.
Lo stato possibile per l'attività è: New
, InProgress
(facoltativo per quanto riguarda le strategie di seguito), Complete
e Fail
.
Varie strategie per l'ascoltatore (presento una iterazione di processo per ciascuna):
Soluzione a thread singolo:
- Interrogazione di un'attività il cui stato è "Nuovo".
- Invio dell'attività al lavoratore
EmailSender
. - Quando l'operatore ha eseguito il lavoro, passando lo stato a
Complete
Professionisti di questa soluzione: sicurezza!
Contro: lento, molto lento ..
Soluzione multi-thread:
- Interrogazione di più attività contemporaneamente il cui stato è "Nuovo".
- Più
EmailSender
di lavoratori sono istanziati: invia tutte le attività a loro - Non appena un operatore ha gestito un'occorrenza, il suo stato corrispondente è impostato su
Complete
. - Nel frattempo i lavoratori stanno elaborando, una nuova query viene elaborata, quindi le attività vengono inviate alle code di lavoro, ecc. essendo il tutto asincrono.
Pro: Wow! Veloce!
Contro: Potenziali condizioni di gara, dal momento che una stessa operazione attualmente elaborata potrebbe essere recuperata nuovamente dalla query successiva poiché l'attuale worker che l'elaborazione potrebbe non essere ancora completata = > È possibile inviare più di un'occorrenza di posta! Male!
Soluzione multi-thread che coinvolge lo stato InProgress
:
- Interrogazione di più attività contemporaneamente il cui stato è "Nuovo".
- Aggiornamento immediato di quelle attività con lo stato
InProgress
. - Più
EmailSender
di lavoratori sono istanziati: invia tutte le attività a loro - Non appena un operatore ha gestito un'occorrenza, il suo stato corrispondente è impostato su
Complete
. - Nel frattempo i lavoratori stanno elaborando, una nuova query viene elaborata, quindi le attività vengono inviate alle code di lavoro, ecc. essendo il tutto asincrono.
Pro: multi-threaded e sicurezza! Niente più mail del previsto!
Contro: Aumentare l'accesso al database ... per contrassegnare lo stato come InProgress
.. possibile conflitto sul database con un numero enorme di eventi.
Soluzione multi-threading che evita le query mentre almeno un worker è ancora in fase di elaborazione:
- Interrogazione di più attività contemporaneamente il cui stato è "Nuovo".
- Più
EmailSender
di lavoratori sono istanziati: invia tutte le attività a loro - Non appena un lavoratore ha raggiunto un compito, il suo stato corrispondente è impostato su
Complete
. - Nel frattempo i lavoratori stanno elaborando, una nuova query viene elaborata, quindi le attività vengono inviate alle code di lavoro, ecc. essendo il tutto asincrono.
Pro: multi-threaded, sicurezza! Non è necessario coinvolgere uno stato di blocco come InProgress
!
Contro: Se per qualsiasi motivo, una mail impiega 8 secondi per essere inviata, ritarderà la prossima query!
Molti lavori potrebbero essere visti come inattivi, in attesa della prossima query ...
Quale soluzione dovrei usare?
C'è qualche altra soluzione efficiente?