Usare code di messaggi in .net core – parte 2: i Background Worker

Usare code di messaggi in .net core – parte 2: i Background Worker

2019, Jul 10    

Ed eccoci al secondo articolo della Serie. Nello scorso appuntamento abbiamo parlato un po’ delle Code di Messaggi, questa volta invece introdurremo i Background Worker.

Giusto per rinfrescare un po’ la memoria, le Code di Messaggi possono essere usate per gestire le comunicazioni asincrone tra microservizi, migliorando resilienza e scalabilitá.

Ora supponiamo di avere un’API per gestire post e tag di un blog. Ad ogni post possono essere associati uno o piú tag. Diciamo pure che abbiamo come strato di persistenza MongoDb con una sola collection “Posts”. Qualcosa di semplice:

{
    title: ...,
    description: ...,
    creationDate: ...,
    tags: ["lorem", "ipsum", "dolor"]
}

Funziona bene, le API riescono a gestire un bel po’ di richieste. Tutti sono felici e contenti.

Un giorno peró ci viene chiesto di aggiungere la funzionalitá di “tag-cloud”: in pratica bisogna esporre un nuovo endpoint che restituisce una lista di tutti i Tag con tanto di conteggio dei Post. Qualcosa tipo:

[
    {tag: "lorem", posts_count: 42},
    {tag: "ipsum", posts_count: 13},
    {tag: "dolor", posts_count: 71}
]

Di nuovo nulla di spaziale. Adesso peró la domanda è : come creiamo i dati?

La prima opzione potrebbe essere di aggiungere una nuova collezione per i Tag ed aggiornarne il contenuto con un upsert ogni volta che un Post viene creato o modificato.

Funziona benino ma non é particolarmente scalabile: l’intera operazione potrebbe richiedere tempo oppure fallire e quindi lasciarci con il db in uno stato inconsistente.

Sicuramente potremmo aggiungere un Circuit Breaker ma sono sicuro che non ci toglierebbe completamente dai guai.

Un’altra opzione invece é quella di usare un Background Worker: in soldoni all’avvio dell’applicazione facciamo partire un thread secondario ed eseguire quindi in background qualunque operazione ci serve.

Tornando al nostro piccolo esempio, il nostro Background Worker si occuperá ad intervalli regolari di svuotare la collezione dei Tag e ricrearla da zero. Potremmo farlo partire ogni 6 ore ad esempio ma questo ovviamente dipende molto dalla frequenza di aggiornamento dei Post.

Visto che stiamo usando MongoDb, potremmo sfruttare un map/reduce oppure l’aggregate pipeline, non fa molta differenza (in veritá si, ma non é il punto oggi).

I Background Worker possono essere usati anche per consumare messaggi pubblicati su una coda: Ad esempio possiamo gestire un evento “Ordine spedito” ed inviare un’email di notifica al cliente.

È un’operazione totalmente asincrona che puó essere fatta offline, al di fuori del contesto web, quindi un candidato perfetto per un Background Worker.

Altra cosa che potremmo fare è gestire l’evento “Post creato” ed aggiornare i dati denormalizzati nel db delle query, ottenendo cosí un’architettura CQRS (magari con persistenza poliglotta).

E per oggi è tutto. La prossima volta le cose si faranno piú interessanti perché andremo ad analizzare un po’ di codice.