Avantages de Orleans

Les principaux avantages de Orleans sont :

  • la productivité des développeurs, même pour des programmeurs débutants ;
  • la scalabilité transparente par défaut sans effort spécial de la part du programmeur.

Productivité des développeurs

Le modèle de programmation Orleans améliore la productivité des programmeurs expérimentés et débutants en fournissant les abstractions clés, les garanties et les services système suivants.

Paradigme familier de la programmation orientée objet (OOP)

Les grains sont des classes .NET qui implémentent des interfaces de grain .NET déclarées avec des méthodes asynchrones. Les grains apparaissent au programmeur en tant qu’objets distants dont les méthodes peuvent être appelées directement. Cela fournit au programmeur le paradigme OOP familier en transformant les appels de méthode en messages, en les acheminant vers les points de terminaison appropriés, en appelant les méthodes du grain cible et en gérant de façon transparente les défaillances et les cas extrêmes.

Exécution monothread des grains

Le runtime garantit qu’un grain ne s’exécutera jamais sur plusieurs threads à la fois. Combiné à l’isolement par rapport aux autres grains, le programmeur ne fait jamais face à une simultanéité au niveau du grain et n’a jamais besoin d’utiliser des verrous ou d’autres mécanismes de synchronisation pour contrôler l’accès aux données partagées. Cette caractéristique facilite à elle seule le développement des applications distribuées pour les programmeurs débutants.

Activation transparente

Le runtime active un grain uniquement quand il y a un message à traiter. Cela distingue clairement la notion de création d’une référence à un grain, visible et contrôlée par le code d’application, de l’activation physique du grain en mémoire, qui est transparente pour l’application. Ceci est similaire à la mémoire virtuelle du fait que cela détermine quand « décharger » (désactiver) ou « charger » (activer) un grain. L’application a un accès ininterrompu à « l’espace mémoire » complet des grains créés logiquement, qu’ils soient ou non dans la mémoire physique à un moment donné.

L’activation transparente permet un équilibrage de charge dynamique et adaptatif via le placement et la migration des grains dans l’ensemble du pool des ressources matérielles. Cette fonctionnalité est une amélioration significative par rapport au modèle d’acteur traditionnel, dans lequel la durée de vie de l’acteur est gérée par l’application.

Transparence des emplacements

Une référence de grain (objet proxy) que le programmeur utilise pour appeler les méthodes du grain ou pour les passer à d’autres composants contient uniquement l’identité logique du grain. La traduction de l’identité logique du grain vers son emplacement physique et le routage correspondant des messages sont effectués de manière transparente par le runtime Orleans.

Le code d’application communique avec les grains sans pour autant être conscient de leur emplacement physique, ce qui peut changer au fil du temps en raison d’échecs ou de la gestion des ressources, ou parce qu’un grain est désactivé au moment où il est appelé.

Intégration transparente avec un magasin persistant

Orleans permet le mappage déclaratif de l’état en mémoire d’un grain vers un magasin persistant. Il synchronise les mises à jour de façon transparente, ce qui garantit que les appelants reçoivent les résultats uniquement après la mise à jour de l'état persistant. L’extension et/ou la personnalisation de l’ensemble des fournisseurs de stockage persistant existants disponibles sont simples.

Propagation automatique des erreurs

Le runtime fait automatiquement remonter les erreurs non gérées le long de la chaîne d’appels avec la sémantique d’une commande try/catch asynchrone et distribuée. Par conséquent, les erreurs ne sont pas perdues dans une application. Cela permet au programmeur de mettre la logique de gestion des erreurs aux emplacements appropriés sans l’effort fastidieux d’avoir à propager manuellement les erreurs à chaque niveau.

Scalabilité transparente par défaut

Le modèle de programmation Orleans est conçu pour guider le programmeur sur le chemin d’une réussite probable en mettant à l’échelle une application ou un service selon plusieurs ordres de grandeur. Ce processus s’effectue en incorporant les bonnes pratiques et les meilleurs modèles éprouvés, et en fournissant une implémentation efficace des fonctionnalités du système de niveau inférieur.

Voici quelques facteurs clés qui favorisent la scalabilité et les performances :

Partitionnement implicite granulaire de l’état de l’application

En utilisant des grains en tant qu’entités directement adressables, le programmeur décompose implicitement l’état global de l’application. Bien que le modèle de programmation Orleans ne prescrive pas la taille requise d’un grain, dans la plupart des cas, il est judicieux d’avoir un nombre relativement élevé de grains (des millions ou plus), chacun représentant une entité naturelle de l’application, comme un compte d’utilisateur ou une commande d’achat.

Avec les grains qui sont adressables individuellement et leur emplacement physique rendu abstrait par le runtime, Orleans dispose d’une grande flexibilité pour équilibrer la charge et traiter les points chauds de manière transparente et générique sans que le développeur d’applications ait à y penser.

Gestion adaptative des ressources

Les grains ne supposent pas la localité d’autres grains quand ils interagissent avec eux. En raison de cette transparence des emplacements, le runtime peut gérer et ajuster l’allocation des ressources matérielles disponibles de façon dynamique. Pour ce faire, il prend des décisions très précises sur le placement et la migration des grains dans l’ensemble du cluster de calcul en réaction à des modèles de charge et de communication, sans faire échouer les demandes entrantes. En créant plusieurs réplicas d’un grain particulier, le runtime peut augmenter le débit du grain sans apporter de modifications au code de l’application.

Communication multiplexée

Les grains dans Orleans disposent de points de terminaison logiques, et la messagerie entre eux est multiplexée sur un ensemble fixe de connexions physiques toutes-vers-toutes (sockets TCP). Le runtime peut ainsi héberger des millions d’entités adressables sans aucune surcharge du système d’exploitation par grain. En outre, l’activation ou la désactivation d’un grain n’entraîne pas le coût d’inscription/annulation de l’inscription d’un point de terminaison physique, tel qu’un port TCP ou une URL HTTP ou même la fermeture d’une connexion TCP.

Planification efficace

Le runtime planifie l'exécution d'un grand nombre de grains monothread à l'aide du pool de threads .NET, hautement optimisé pour les performances. Le code du grain étant écrit dans le style de continuation sans blocage (une exigence du modèle de programmation Orleans), le code de l’application s’exécute d’une manière multithread « coopérative » très efficace et sans conflit. Cela permet au système d’atteindre un débit élevé et de s’exécuter avec une très forte sollicitation du processeur (jusqu’à 90 % ou plus) et une grande stabilité.

Le fait qu’une croissance du nombre de grains dans le système et une augmentation de la charge n’entraînent pas de threads supplémentaires ou d’autres primitives de système d’exploitation favorise la scalabilité des nœuds individuels et de l’ensemble du système.

Comportement asynchrone explicite

Le modèle de programmation Orleans rend explicite la nature asynchrone d’une application distribuée et incite les programmeurs à écrire du code asynchrone non bloquant. Combiné à la messagerie asynchrone et à une planification efficace, cela permet un haut degré de parallélisme distribué et un débit global sans l’utilisation explicite du multithreading.