Récemment, dans un projet, un problème de performance est apparu concernant l'exportation d'un fichier Excel. Le scénario impliquait un point de terminaison qui devait interroger la base de données et renvoyer un grand volume de données à exporter par la suite.

 

Cependant, la même requête, dans un autre point de terminaison, renvoyait les données pour être affichées à l'utilisateur côté front-end, mais le problème de performance a été résolu grâce à la pagination. Cependant, le scénario de génération de fichier n'était pas bien exécuté, car l'exigence était d'exporter tout ce qui était disponible en fonction du filtre appliqué.

Eh bien, après avoir effectué quelques tests, j'ai réalisé que l'utilisateur devrait attendre longtemps que le processus soit terminé. Cela ne serait pas idéal, car l'utilisateur pourrait quitter la page ou même renoncer au rapport. C'est alors que j'ai commencé à réfléchir à des solutions pour résoudre ce problème.

Un autre problème très courant dans divers projets est d'avoir un budget limité. J'ai donc commencé à réfléchir à l'utilisation d'une file d'attente : de cette façon, l'utilisateur ferait la demande et ne serait pas bloqué sur la page en attendant.

Actuellement, nous disposons de nombreuses options de services de file d'attente, tels que RabbitMQ, Kafka, entre autres, mais ce sont des outils puissants qui nécessitent parfois des mises en œuvre complexes, ce qui ne serait pas réalisable pour ce scénario.

Alors j'ai pensé que .NET fournit nativement un service appelé "BackgroundService", qui implémente l'interface "IHostedService", et cela ouvre une série d'avantages. Je n'ai pas besoin de m'inquiéter des serveurs externes, des mises en œuvre complexes, et surtout : tout fonctionne sur le même service d'application que mon API, indépendamment.

  

Pratiquons...

Comme toujours, nous fournirons un exemple réel !

1. Créons un projet exemple. Pour ce faire, sélectionnez l'option "Créer un nouveau projet".


Background Service Queue 1
2. Nommez la solution.

Background Service Queue 2
3. Sélectionnez la version .NET.


Background Service Queue 3
4. Nous allons créer les dossiers logiques suivants :


Background Service Queue 4
5. Installez le package Bogus : "Install-Package bogus".
6. Créons les classes Customer et Invoice. Dans la classe Customer, voici les propriétés :
:

Background Service Queue 5
7. Créer la classe Invoice.

Background Service Queue 6

Remarquez que les propriétés sont en lecture seule. C'est une bonne pratique, donc pour créer une facture, nous aurons besoin d'un constructeur comme ceci :


Background Service Queue 7
8. La classe Customer suit le même modèle, car ses setters sont privés. Par conséquent, nous allons implémenter un constructeur et également la méthode qui renverra une liste de Clients.

Background Service Queue 8

Notez qu'un Client est créé en instanciant la classe et en communiquant au constructeur le nom et s'il est actif. Le nom est représenté par un texte qui incrémente un nombre à chaque itération. Être actif dépend de savoir si le numéro d'itération (i) est pair ou impair.

Les factures fonctionnent de la même manière.



Background Service Queue 9

Remarquez que j'ajoute 5 factures pour chaque Client créé. Pour ce faire, nous allons créer la méthode AddInvoice dans la classe Customer.


Background Service Queue 10
9. Créons maintenant l'interface responsable de l'enregistrement ou du désenregistrement de nos objets. L'interface s'appellera "IBackgroundQueue". 

Background Service Queue 11
10. Créez ensuite la classe concrète qui implémentera cette interface.


Background Service Queue 12
11. Créez une autre interface. Nous l'appellerons "ICustomerPublisher." Cette interface devrait avoir une méthode de publication.


Background Service Queue 13
12. Ensuite, implémentez simplement l'interface dans une classe nommée "CustomerPublisher" dans le dossier "Services".

Background Service Queue 1413. Une grande partie du travail est déjà faite. Jusqu'à présent, nous avons : 
- IBackgroundQueue : une interface pour inclure et exclure de la file d'attente ; 
- ICustomerPublisher : une interface qui gère la publication dans la file d'attente ; 
- BackgroundQueue et CustomerPublisher : des implémentations concrètes des interfaces ; 
- Modèles Client et Facture.


14. La prochaine étape consiste à créer notre worker, qui sera responsable de l'exécution du processus de file d'attente. Ce processus s'exécute en parallèle de l'API, c'est donc un service hébergé dans la même application, sans interférer réellement avec l'API. Nous allons créer une classe appelée "CustomerBackgroundWorker," qui devrait hériter de la classe abstraite "BackgroundService". Cette dernière est responsable de fournir les fonctionnalités que nous devons implémenter dans la classe - un exemple est la méthode "ExecuteAsync", qui est un remplacement requis dans notre classe.

.

Background Service Queue 15

Il est important de noter que nous devons injecter notre service de file d'attente. J'inclus également ici ILogger, afin que nous puissions voir le résultat dans la console.

L'interface "IServiceScopeFactory" est très importante - elle nous permet d'utiliser le service de publication. Normalement, nous utiliserions le processus d'injection de dépendances habituel lorsque l'application démarre. Cependant, la construction de l'instance est différente lorsque nous utilisons des services hébergés. Il y a un conflit dans la création du scope, donc la bonne façon de faire est de le faire dans ce service en utilisant l'interface "IServiceScopeFactory".

15. Maintenant, nous implémentons la méthode qui met notre objet dans la file d'attente ou le supprime par la publication.


Background Service Queue 16
16. N'oubliez pas d'ajouter nos fonctionnalités à la portée du service dans la classe "Program.cs".

Background Service Queue 17

17. Enfin, nous allons créer le contrôleur "CustomersController". Déclenchons une situation d'attente des clients.

Background Service Queue 18

18. Maintenant, pour le tester, nous allons cliquer plusieurs fois via Swagger pour créer les demandes et observer les journaux dans la console. Nous pouvons conclure que nous envoyons de manière asynchrone les clients qui seront traités ultérieurement, et le consommateur, qui fait la demande, ne sera pas bloqué en attendant une réponse de l'API.

Dans mon cas, j'avais déjà cliqué plus de 10 fois, j'avais déjà la réponse de l'API, et le processus de publication était toujours en cours, comme le montre l'image.

Background Service Queue 19

 

Conclusion

Il s'agit d'une excellente fonctionnalité native qui peut grandement nous aider lorsque nous voulons utiliser une file d'attente sans complexité et pour des objectifs spécifiques. Un excellent exemple serait de créer un service d'envoi d'e-mails pour une règle métier spécifique, comme l'envoi d'e-mails de traitement des paiements aux clients.



Lien utiles :
Partager cet article