Buona strategia per implementare attività di elaborazione listener fornite dal database

1

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?

    
posta Mik378 11.03.2014 - 01:55
fonte

1 risposta

1

Ci sono due domande chiave da considerare. Una volta che rispondi a quelle, il resto dovrebbe andare a posto.

Il primo è: chi blocca? Nella soluzione ST, la coda del programma di pianificazione blocca l'attesa per il completamento di un singolo server. Nella soluzione MT i server bloccano quando non hanno più lavoro da fare e l'ascoltatore blocca solo quando non c'è niente da fare. Il throughput massimo richiede MT e server in eccesso. Altre considerazioni potrebbero limitare il numero.

Il secondo è: chi lo sa? Se lo stato dell'attività è pubblico, noto a tutti e aggiornato dalle attività, gli accessi al database saranno limitati. Se lo stato dell'attività è privato, noto solo a e aggiornato solo dal listener, gli aggiornamenti del database non sono più un collo di bottiglia (è possibile aggiornarli occasionalmente per comunicare al mondo esterno).

Quindi un ascoltatore con uno stato di attività privata (nella struttura dei dati della memoria) e abbastanza attività del server di posta elettronica per ridurre al minimo i tempi di attesa dovrebbe soddisfare tutti i requisiti che hai dichiarato. Nessuna condizione di gara, nessuna attesa inutile, accesso completamente sicuro e controllato al database. Joy.

    
risposta data 11.03.2014 - 11:05
fonte

Leggi altre domande sui tag