Technologie
Slimmer background jobs beheren in .NET met Hangfire
In ons eerdere blog bespraken we hoe Hangfire helpt om op een eenvoudige manier achtergrondtaken te beheren en te automatiseren binnen .NET. Daar stonden we stil bij wat Hangfire kan en hoe de verschillende typen taken te gebruiken zijn. In dit blog laten we zien hoe we dit in de praktijk toepassen.
Een goed praktijkvoorbeeld van de voordelen van Hangfire is het versturen van e-mail, bijvoorbeeld na het invullen van een contactformulier op je website. In veel applicaties wordt het versturen van een mail direct uitgevoerd binnen het HTTP-request. Dat lijkt logisch, maar brengt risico’s met zich mee. Het mailen kost namelijk relatief veel tijd en is kwetsbaar voor netwerkproblemen of een niet-beschikbare mailserver. Hierdoor moet de gebruiker wachten op de afhandeling, of krijgt zelfs een foutmelding als het misgaat.
Door het versturen van e-mail te ontkoppelen van het HTTP-request en deze taak als background job door Hangfire te laten uitvoeren, voorkom je deze problemen. De gebruiker ontvangt direct een bevestiging, terwijl de e-mail op de achtergrond betrouwbaar wordt verwerkt. Laten we kijken hoe Hangfire daar het verschil maakt.
Waarom je geen e-mails wilt versturen binnen het HTTP-request
Als eerste voorbeeld gebruiken we een tightly-coupled request dat na het aanmaken van een order een bevestigingsmail verstuurt. We hebben SendOrderConfirmationAsync zo geimplementeerd dat deze een SMTP-probleem zal simuleren. Het aanroepen van deze method geeft zoals verwacht een foutmelding.


Als we nu terugkijken naar wat we eigenlijk wilden doen, zien we dat het aanmaken van de order wel degelijk gelukt is. We willen de gebruiker dus een terugkoppeling geven dat dit gelukt is. Wat het verzenden van de e-mail betreft, willen we dat dit opnieuw geprobeerd wordt. Ook dat kan binnen het HTTP-request geïmplementeerd worden, maar dan zou de gebruiker moeten wachten tot de uiteindelijke geslaagde poging totdat de applicatie het resultaat teruggeeft. We gaan hiervoor Hangfire inzetten, met een ingebouwd retry-mechanisme:

De actie die we eerst rechtstreeks uitvoerden, laten we nu als achtergrondtaak inschieten. Met hetzelfde request zien we nu meteen een succes-statuscode verschijnen. In het Hangfire-dashboard zien we vervolgens dat er een taak verschijnt.

Inzicht met het Hangfire-dashboard
Eén van de krachtigste features van Hangfire is het ingebouwde monitoring dashboard.
Hierin kun je live zien wat er gebeurt:
-
De status van je taken
-
De foutmeldingen
-
En het opnieuw starten van mislukte of geplande jobs
Wat we nu zien is dat onze taak verschijnt onder het tabje ‘Retries’.
Als reden van het mislukken van de taak zien we de ons inimddels bekende SMTP-problemen. Ook zien we dat in de tijd dat we dit scherm geopend hebben, dit al een tweede poging is. Hangfire voert uit zichzelf 10 pogingen uit om de mail te verzenden. Laten we onze MailSender nu zo aanpassen dat deze bij de derde poging wel slaagt. Ondertussen passen we ook eigen configuratie toe op Hangfire’s retry-mechanisme: we willen maximaal vier pogingen en we willen invloed op de tijd tussen de pogingen.

We zien onze taak nu tussen de ‘Succeeded jobs’ staan. Als het een taak lukt om binnen de maximaal gestelde pogingen te voltooien, dan wordt dit gezien als een succes. Lukt dat niet, dan gaat de status van de taak na de laatste poging naar ‘Failed’. Gelukkig hebben we ook daar de mogelijkheid om de taken gewoonweg opnieuw uit te voeren.
Zorg dat je code idempotent is
Zoals met elk retry-mechanisme, moet hier wel rekening mee gehouden worden in de implementatie van de taak. Als we deze logging bekijken van het proces dat onze taak heeft doorlopen, dan zien we goed terug dat onze code meerdere keren wordt uitgevoerd. Het is daarom belangrijk dat onze code idempotent is; omdat precies dezelfde method die aan de basis van onze task staat, met precies dezelfde parameters zal worden aangeroepen bij een retry.
Betrouwbaar en gebruiksvriendelijk
Hangfire stelt ons in staat om achtergrondtaken slim en betrouwbaar te verwerken, zonder dat je gebruikers onnodig hoeft op te zadelen met wachttijden of foutmeldingen. Het ingebouwde dashboard geeft direct inzicht in de status en uitvoering van je taken, en het retry-mechanisme zorgt ervoor dat kritieke acties automatisch opnieuw worden geprobeerd als er iets misgaat. Door je taken idempotent te maken, voorkom je dubbele acties bij herhaalde pogingen en houd je je processen stabiel en voorspelbaar. Hiermee helpt Hangfire zowel de flexibiliteit voor ontwikkelaars, als de robuustheid van de applicatie voor eindgebruikers.
Geschreven door: David de Rijke
Meer weten? Neem contact op!
Michiel Leenaers
Business Development
0614688177
m.leenaers@garansys.nl