Un'applicazione robusta deve essere disegnata in modo da tenere in considerazione che le risorse esterne a cui accediamo, siano esse database o servizi, possano temporaneamente fallire. Questo è soprattutto vero in uno scenario cloud, in cui la stessa natura disconnessa dell'ambiente può essere causa di questi fault.
Spesso si tratta di problemi che durano lo spazio di qualche millisecondo, per cui, prima di restituire un messaggio di errore all'utente, può valere la pena effettuare un nuovo tentativo. Piuttosto che scrivere a mano il codice necessario, possiamo sfruttare una libreria come Polly: si tratta di un package NuGet che mette a disposizione una serie di primitive per gestire questo tipo di necessità.

Immaginiamo allora di avere un'interfaccia IContentService che astragga una chiamata al database o a una generica risorsa esterna:
public interface IContentService { Task<string[]> LoadArticlesAsync(); }
Normalmente, il nostro codice sul controller sarebbe qualcosa di simile al seguente:
private IContentService _content; public async Task<IActionResult> Index() { var articles = await _content.LoadArticlesAsync(); return View(articles); }
Ovviamente, in questo modo, una singola eccezione sulla connessione, causerebbe un errore e quindi una risposta di StatusCode 500 restituita all'utente.
Cerchiamo di capire come possiamo rendere allora l'applicazione più robusta. Il concetto base di Polly è rappresentato dalla classe Policy, tramite la quale possiamo specificare il comportamento che desideriamo implementare. Nel nostro caso, vogliamo effettuare in automatico qualche Retry, prima di fallire definitivamente.
public async Task<IActionResult> Index() { var policy = Policy .Handle<Exception>() .RetryAsync(retryCount:3); var articles = await policy.ExecuteAsync( () => _content.LoadArticlesAsync()); return View(articles); }
La fluent interface di Polly rende tutto estremamente leggibile e chiaro: tramite il metodo Handle abbiamo specificato che vogliamo gestire ogni possibile eccezione, ma ovviamente è possibile isolarne alcune specifiche. Successivamente, con RetryAsync, abbiamo indicato che vogliamo riprovare al massimo per 3 volte. Esistono diversi overload di questo metodo, alcuni con un callback che viene invocato automaticamente a ogni retry, così che possiamo per esempio loggare comunque l'errore.
L'ultimo step è la chiamata a ExecuteAsync, alla quale abbiamo passato il metodo effettivamente da eseguire.
Il codice in allegato mostra il tutto in funzione, con un'implementazione fittizia di IContentService che restituisce una risposta con successo solo al terzo tentativo.
Questo è solo un utilizzo basilare di Polly, nei prossimi script daremo un'occhiata a ulteriori funzionalità, utilissime per rendere più robusta la nostra applicazione.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Popolare una classe a partire dal testo, con Semantic Kernel e ASP.NET Core Web API
Change tracking e composition in Entity Framework
Migliorare l'organizzazione delle risorse con Azure Policy
Filtrare i dati di una QuickGrid in Blazor con una drop down list
Aggiornare a .NET 9 su Azure App Service
Simulare Azure Cosmos DB in locale con Docker
Configurare lo startup di applicazioni server e client con .NET Aspire
Sfruttare GPT-4o realtime su Azure Open AI per conversazioni vocali
Effettuare il log delle chiamate a function di GPT in ASP.NET Web API
Creare una libreria CSS universale - Rotazione degli elementi
Generare velocemente pagine CRUD in Blazor con QuickGrid
Recuperare l'ultima versione di una release di GitHub
I più letti di oggi
- Beta 1 di VS 2005 Enterprise Architect
- Point-in-time restore con gli Azure Storage Blob
- Focus dei tag input con HTML5
- Il nuovo tag nav in HTML5
- Evitare la modalità di risparmio energetico in una Windows Store app
- Real Code Day 4.0: costruire applicazioni reali - Firenze
- AI&ML Conference 2019 - Milano
- Mono 0.12: verso una nuova implementazione di ASP.NET