Au cours de la semaine passée, je me suis aventuré dans le développement logiciel en recherchant le concept d’acteurs virtuels. J’ai fini par explorer deux cadres différents : Dapr et Orléans.
Les deux sont des projets très concis avec de nombreux cas d’usage intéressants. Les deux utilisent l’idée d’acteurs « virtuels ». Un acteur virtuel est une unité d’état et de logique qui :
- Elle peut être identifiée de manière unique par l’ID
- Il est à simple filetage
- Peut être en mémoire ou persistante – son cycle de vie est géré par le framework
J’aime beaucoup l’idée des acteurs virtuels et je les trouve très utiles dans mon exploration de la création d’outils évolutifs et fiables pour gérer des flux de travail complexes. Si chaque tâche est un participant virtuel monothread, le problème de la condition de race disparaît.
Parce qu’Orléans et Dapr sont tous deux des projets Microsoft, j’imagine une journée dans un affrontement à la Western Story à la cafétéria Microsoft.
Orléans
J’ai commencé par Orleans parce que ça me préoccupe depuis un moment après avoir vu quelques vidéos à ce sujet sur YouTube. Ça a vraiment mal commencé parce que je pensais utiliser la version 4.x de tous leurs packages NuGet. Cependant, absolument aucune de leurs documentations ne fonctionne avec le package 4.x. J’ai fini par utiliser la version 3.6.2.
Céréales / État / Minuteurs
Créer un grain qui suit son propre état et effectue des actions est très simple. J’ai même pu suivre la documentation sur la persistance des grains et créer ma propre implémentation CosmosDB (API SQL) D’IGrainStorage.
Rappels
Les rappels sont aussi faciles à configurer. Jusqu’à ce que j’essaie de configurer la persistance réelle pour eux. À ce stade de mes recherches, j’essaie de tout garder propre et de tout stocker dans ComsosDB. Malheureusement, je n’arrive pas du tout à faire fonctionner le pack de rappel de persistance d’Orléans. J’ai finalement dû passer au package AzureStorage. Donc maintenant, mes données sont à moitié dans le compte SQL API et à moitié dans le compte API de table.
Flux
C’est là que je ne m’en suis pas bien sorti. À Orléans, les flux sont identifiés par un GUID et un espace de noms optionnel. Je suis sûr qu’il y a une bonne raison pour laquelle les flux doivent être identifiés par un GUID, mais wow, c’est peu pratique.
Je suis très frustré par les streams parce que j’ai pu les créer facilement, mais dès que j’arrête, redémarre mon projet et déclenche un nouvel événement, tout plante.
Cela est suivi d’une information très précieuse, car il m’a fallu 8 heures pour rétroconcevoir le code d’Orléans afin de le comprendre :
Lorsqu’un grain est abonné à un stream, il doit appeler ResumeAsync sur le handle d’abonnement dans sa méthode OnActivateAsync, sinon vous plantez avec une erreur non reconnue.
J’ai aussi eu le problème du même abonnement qui était dupliqué, alors j’ai utilisé le code pour supprimer tous les abonnements du grain puis je l’ai recréé :
Autres pièges / conseils à Orléans
Streams fonctionne bien avec Azure Event Hubs (via AddEventHubStreams).
N’utilisez pas / ni d’autres caractères spéciaux dans le nom Grain de l’API SQL de CosmosDB !
Conclusion d’Orléans
J’aime Orléans et je pense qu’il a du potentiel. Cependant, la courbe d’apprentissage est très raide. À cause de mes longues difficultés avec le streaming, je n’ai pas le temps d’étudier comment fonctionnent les clusters et les déploiements.
Dapr
J’ai découvert Dapr en cherchant des alternatives à Orléans. C’est un peu étrange que ce soit aussi un projet sponsorisé par Microsoft. Peut-être sont-ils là pour adopter une approche de la survie du plus apte. Si oui, je pense que Dapr sera un survivant.
Premièrement, la conception basée sur REST/gRPC de Dapr permet d’implémenter des acteurs en utilisant n’importe quel langage de programmation. J’ai aussi trouvé trivial de tout exécuter (participants, statuts, minuteries, rappels, événements) sur une seule instance Redis. En plus de ça, il ne m’a fallu qu’environ un tiers du temps pour commencer à utiliser Dapr. Un tel temps de démarrage rapide est dû à l’excellente documentation de Dapr.
Acteurs / Chronométreurs / Rappels
Ai-je juste dit que la documentation de Dapr est excellente ? Eh bien, c’est partout, sauf pour les exemples JavaScript. Je passe la plupart de mon temps sur Dapr, essayant de comprendre comment appeler les méthodes sur les acteurs. Le code de l’exemple Dapr Javascript est le suivant :
C’est clairement dépassé. J’ai dû passer beaucoup de temps à faire passer ces trois lignes à travers l’exploration de code test/exemple de Dapr
Les exemples de code pour obtenir/définir l’état ont des problèmes similaires, donc j’ai créé un issue GitHub pour eux.
À part ces petits problèmes, préparer les acteurs est un jeu d’enfant.
Régler des minuteurs et des rappels pour mon lancer est aussi très simple.
État
J’ai pu configurer Dapr pour qu’il persiste avec Postgres très facilement.
Une chose que j’ai remarquée, c’est qu’il peut y avoir des problèmes de scalabilité dans la façon dont les rappels sont stockés. Dapr stocke toutes les alertes d’un type de participant spécifique dans un seul tableau JSON. Que se passe-t-il si quelqu’un a énormément de rappels ?
Autres pièges / conseils sur Dapr
Une chose que j’ai remarquée en parcourant le code du SDK JavaScript, c’est qu’il n’y a pas beaucoup de commentaires dans la base de code. Cela rend presque impossible de comprendre quelque chose. Par exemple, dans la méthode addOrUpdateState du gestionnaire d’état, il existe un troisième paramètre appelé updateValueFactory. S’il n’y a pas de commentaires dans le code, il est presque impossible de savoir à quoi sert le rappel.
Je ne suis pas sûr non plus de l’appréciation de la commande « dapr init » qui essaie de configurer et d’exécuter un conteneur Redis pour moi. Et si j’ai déjà un contenant Redis ? Et si je préférais utiliser des postgres à la place ? Je ne trouve pas de documentation expliquant comment changer la fonction DAPR Init.
Une note pour tous ceux qui ont des difficultés à utiliser pubsub. Vous devez utiliser « dapr run » pour gérer à la fois votre éditeur et votre abonné :
Pour les acteurs et pubsub, notez qu’il est important d’utiliser le paramètre --app-port pour informer dapr sur quel port votre service tourne. Les événements pubsub et les appels d’acteurs sont envoyés à votre service depuis le sidecar Dapr via des appels HTTP, il doit donc savoir où les envoyer :
J’ai testé un petit « cluster » Dapr auto-hébergé en lançant mon instance d’abonné pubsub sur deux machines différentes de mon réseau domestique. Ça a juste marché !
Conclusion de Dapr
Si vous souhaitez en savoir plus sur les applications distribuées ou les acteurs virtuels, je vous recommande de commencer par Dapr. Orleans était le pionnier original, tandis que Dapr était un reboot qui a poussé les choses à un autre niveau.
Lien original :La connexion hyperlientérée est visible.
|