Varda : a language for programming distributed systems by composition
Varda : un langage pour la programmation de systèmes distribués par composition
Résumé
Large distributed systems are often built by assembling off-the-shelf (OTS) components, e.g., components, services, processes, etc., developed independently. The current approach is to interconnect their APIs manually. This is ad hoc, complex, tedious, and error-prone. Programming languages offer a promising approach to addressing this problem. First, they could help reduce the occurrence of bugs. The programmer specifies the system using well-defined entities and constraints. Then, the compiler a correct-by-construction implementation providing various guarantees (e.g., that communications are correctly ordered). Furthermore, languages could help improve programmers’ productivity. The code generation offloads the boilerplate plumbing to the compiler. In addition, the compiler might perform optimizations leveraging its knowledge of the system. In this thesis, we propose a new language, Varda, at the intersection between programming and specification languages. A Varda program describes how to compose components into a coherent architecture. To ensure safety, the programmer isolates an OTS component behind a Varda shield. The shield restricts the component’s behaviour by specifying its interface, its protocol (i.e., what it may send or receive, and in what order), and pre- and post-conditions. Components can be logically nested, to provide encapsulation. An outer component orchestrates its inner components, spawning or killing component instances, interconnecting them, and supervising error conditions; it can intercept and manipulate communication, and more generally compute over components and messages. Varda provides strong guarantees (e.g., isolation between components), enforcing the specification by static analysis, by run-time checks, and by sandboxing. At the same time, to be useful for the development of real, practical distributed systems, Varda takes a pragmatic approach. A shield can contain non-Varda adaptor code (e.g., Java) in order to incorporate black-box OTS components. Varda provides control over non-functional properties that are relevant for performance and fault tolerance, for instance elasticity, placement, and inlining. The Varda compiler automates the generation of boilerplate glue code to make components work together. Varda supports non-stop execution, thanks to supervision mechanisms. We demonstrate the expressiveness and the ergonomic of Varda by encoding classical distributed patterns (e.g., sharding and access control). To illustrate how Varda helps build a real distributed system, we implement a clone of the AntidoteDB geo-replicated datastore. Varda applications are compact, and exhibit modular and reusable design. Our experiments show that the run-time overhead is modest, thanks to compile-time verification andoptimizations.
Les grands systèmes distribués sont souvent construits en assemblant des composants prêts à l’emploi (OTS), c’est-à-dire des composants, des services, des processus, etc., développés indépendamment. La pratique actuelle consiste à interconnecter manuellement leurs API. Cette méthode est ad hoc, complexe, fastidieuse et sujette aux erreurs. Les langages de programmation offrent une approche prometteuse pour résoudre ce problème. Premièrement, ils permettent de réduire l’apparition de bogues. Le développeur spécifie formellement le système. Ensuite, le compilateur assure des garanties de correction et génère une implémentation correcte par construction. Deuxièmement, les langages contribuent à améliorer la productivité des programmeurs. La génération de code automatise l’interconnexion des composants et peut optimiser l’implémentation générée. Dans cette thèse, nous proposons un nouveau langage, Varda, à l’intersection entre langages de programmation et de spécification. Un programme Varda décrit l’interconnexion de composants en une architecture cohérente. Le développeur isole un composant OTS derrière un shield. Celui-ci restreint le comportement du composant en spécifiant son interface, son protocole (c’est-à-dire ce qu’il peut envoyer ou recevoir, et dans quel ordre), ainsi que des pre/post-conditions. Les composants peuvent être logiquement imbriqués. Un composant externe orchestre ses composants internes, en créant ou en tuant des instances, en les interconnectant et en supervisant leurs erreurs ; il peut intercepter et manipuler leurs communications. Varda fournit des garanties solides, grâce à de l’analyse statique et à de l’injection de tests dynamiques. Pour être utile en pratique au développement de systèmes distribués, Varda adopte une approche pragmatique. Un shield peut contenir du code non-Varda (par ex, Java) afin d’incorporer des composants en boîte noire. Varda permet de contrôler les propriétés non fonctionnelles qui sont importantes pour la performance et la tolérance aux pannes, par exemple l’élasticité, le placement et l’intégration. Le compilateur Varda automatise la génération du code d’interconnexion et d’orchestration. Varda prend en charge l’exécution non-stop, grâce à des mécanismes de supervision. Nous démontrons l’expressivité et l’ergonomie de Varda en programmant des structures distribuées classiques (par exemple, le contrôle d’accès). Pour illustrer l’emploi en condition réelle de Varda, nous implémentons un clone du datastore géorépliqué AntidoteDB. Les applications Varda sont compactes et présentent une conception modulaire et réutilisable. Nos expériences montrent que le surcoût d’exécution est modeste, grâce à la vérification et à l’optimisation au moment de la compilation.
Origine | Version validée par le jury (STAR) |
---|