Il y a 4 semaines · 20 minutes · Back, DevOps

Retour sur le RustFest 2017

Il y a maintenant 1 mois, j’ai eu la chance d’aller au RustFest, une conférence sur le langage Rust s’étant tenue à Zürich. Cet article est un retour sur les conférences que j’ai pu y voir, d’un point de vue très personnel et y incluant mes propres opinions.

Ce RustFest 2017 était composé de conférences le samedi, et d’ateliers le dimanche. La journée du samedi ayant été relativement dense, avec pas moins de 14 talks successifs sur une seule track, je vais tenter ici de vous résumer les points principaux ayant retenu mon attention, et me permettrai de passer sous silence les points non pertinents afin d’éviter de vous faire perdre votre temps.

tl;dr : rendez-vous à la conclusion en fin d’article !

Keynote: A RustFest Carol

Felix Klock débute la journée en nous présentant un historique de Rust via une narration sous forme de conte. L’objectif ? Nous présenter les principaux points d’évolutions de Rust, que ce soit dans le langage lui-même ou ses bibliothèques principales telles que Serde, et ce depuis les prémices de Rust jusqu’à aujourd’hui, avec comme message principal « ne pas avoir peur du changement ».

Pour ceux qui voudraient le rencontrer, Felix est quelqu’un de très sympathique avec beaucoup de recul sur Rust et il organise le meetup Rust Paris; n’hésitez donc pas à aller y faire un tour !

Rust: an alternative to high-level programming languages?

 

Ce second talk apporte un point de vue très intéressant : celui d’un utilisateur « haut niveau » de Rust. L’utilisateur en question ? Une utilisatrice : Elisabeth Henry, auteure française, qui se sert de Rust pour transformer ses livres qu’elle écrit en Markdown vers du HTML et PDF (ce qui me fait vraiment penser à Pandoc mais là n’est pas la question) !

Le profil n’est donc pas celui de quelqu’un qui attache une grande importance au langage en lui-même, mais vraiment à son utilisation.

Pour commencer, elle nous présente sa définition de « high level » : des outils en ligne de commande, applications graphiques, petits jeux, etc., dans lesquels ni la performance ni la stabilité ne sont des problématiques critiques. Des applications sans réel besoin d’interactions bas niveau, et sur lesquelles ont se situerait donc plus au niveau de Java/Python/Ruby en terme de comparaison de cas d’usage.

Elle dresse ensuite un portrait ma foi assez réaliste des langages impératifs : la plupart permettent de faire rapidement et facilement émerger un résultat, mais en autorisant bien souvent d’arriver à ce résultat un peu n’importe comment (« the wrong way »). Les plus populaires sont faciles à prendre en main, mais cachent en réalité beaucoup de complexité, ce qui ne rend pas les choses plus simples sur le long terme.

Malgré son utilisation haut niveau, Élisabeth a pris le temps de comprendre la  notion de références de Rust, qui peuvent être soit partagées, soit mutables, mais pas les deux ! Au final, Rust lui apporte vraiment de la memory safety et évite les data races, et même un utilisateur haut niveau fini par se rendre compte de ces avantages.

Pour résumer : en comparaison à la plupart des langages impératifs, Rust s’avère bénéfique sur le long terme plutôt que le court terme. En effet, la courbe d’apprentissage du langage a beau être relativement raide, le jeu en vaut la chandelle et le langage rend les choses bien plus faciles par la suite, imposant une certaine rigueur qui facilite notamment la gestion des anomalies, la maintenance, ou encore l’acceptation des contributions, et ce dans la mesure où il est presque ardu de faire des erreurs d’implémentation. Au final, les alternatives sur ces avantages seraient les langages fonctionnels qui n’autorisent pas du tout de mutations, mais qui sont moins répandus et potentiellement plus complexes encore à prendre en main.

Macromancy – an introduction to Rust macros

Talk très intéressant sur les macros en Rust… mais de mon point de vue, qui en présente une utilisation impossible à maintenir et tellement loin de l’esprit craftsmanship que je ne m’attarderai pas dessus malgré le côté séduisant de faire le plus de choses possibles lors de la compilation. Les points principaux évoqués sont : macros récursives, imbriquées, et trace macros pour afficher l’expansion des macros.

En résumé : les macros de Rust permettent de faire énormément de choses… presque trop.

Impractical Macros

Pour appuyer le talk précédent, Alex Burka nous a présenté un interpréteur Brainfuck en pures macros Rust, donc capable de comprendre et d’exécuter du code Brainfuck à la compilation.

Bien que très intriguant et démonstratif, ce talk n’a pas vraiment de raison d’être détaillé, sachez juste que c’est possible… For science!

Antimony: a real time distributed stream processing system

Mon point de vue sur ce talk est relativement mitigé. Il nous a été présenté un système d’analyse temps réel de requêtes DNS en Rust basé sur Apache Storm afin de détecter des malwares, par exemple via des noms de domaines connus ou proches, ou via des critères tels que la longueur.

Le talk pourrait se résumer en « On a pris Apache Storm, on a surchargé nos cluster Zookeeper, et on a fini par drastiquement sur-provisionner TOUT et par lancer chaque topologie sur un cluster Storm séparé avec des clusters Zookeeper séparés ». Mention honorable cependant pour pyleus, le framework Python de Yelp pour développer et gérer des topologies Storm. Très peu de Rust donc, même si la présentation de l’architecture mise en place et des problématiques inhérentes reste intéressante.

Au final, la partie la plus intéressante reste sans doute la mention du papier « Héron » de Twitter sur le stream processing, ainsi que la rapide mention des bibliothèques Tokio et Mio pour les IO asynchrones en Rust, sur lesquelles je reviendrai plus tard.

Testing strategies and pattern for efficient TDD in Rust

Je ne suis pas très objectif sur ce talk ; en effet, le speaker est un ami ! Mais vu qu’il s’agit d’un talk plus sur le côté TDD que l’aspect Rust, je pense que vous pourrez en retrouver la majorité sur le reste du blog ou sur son podcast café-craft.

Élément principal côté « TDD en Rust » à retenir : au final le compilateur vérifie déjà tellement de choses et garanti une telle safety par les contraintes qu’il impose que les tests en sont relativement réduits et qu’on peut se concentrer sur les points vraiment utiles plutôt que d’avoir des tonnes de « edge cases ». Par ailleurs, Rust a tendance à faciliter la gestion des cas d’erreurs, ce qui permet de faire émerger un design solide et complet.

A Rust-based Runtime for the Internet of Things

Ce talk nous présentait TockOS, un OS écrit en Rust pour tout ce qui est IoT : semblant de micro-kernel, isolation mémoire, processus en user-space, …

Pourquoi Rust dans un tel contexte ?

Le design de l’OS lui même et des éléments écrits en Rust est disponible dans la documentation de TockOS.

Au final, Rust permet d’avoir exactement ce qu’on cherche sur de l’IoT : de la fiabilité, du contrôle bas niveau et une très faible consommation de ressources.

A hammer you can only hold by the handle

Cette présentation d’Andrea Lattuada était de mon point de vue tout simplement géniale. Elle abordait sous un angle limpide les notions d’ownership et de borrow de variables en Rust, qui sont souvent les notions les plus ardues à « prendre en main » lorsque l’on débute avec le langage.

Ce n’est par conséquent pas vraiment un talk facile à résumer, sans vous renvoyer vers la documentation de Rust… Mais pour préciser un peu, il a réalisé une analogie très intéressante de l’allocation d’objets et de la gestion de leur durée de vie ainsi que l’accès concurrentiel par rapport à une lettre que l’on souhaiterait envoyer :

  • Enveloppe = type Option contenant potentiellement une lettre
  • Lettre = struct
  • Shipping = méthode utilisant l’enveloppe.

Avec cet exemple, il a démontré comment les primitives du langage nous permettent d’avoir une garantie d’« exactly once » sur certains appels, une garantie d’ordre ainsi qu’une garantie de drop/free.

Fearless concurrency in your microcontroller

Ce talk présentait une gestion bas niveau de la concurrence en Rust, avec comme fil rouge la problématique suivante :

  • Tâche 1 : doit se lancer toutes les 10ms et prend 2ms à s’exécuter
  • Tâche 2 : doit se lancer toutes les 1ms et prend 100µs à s’exécuter
  • Est-il possible de respecter ces contraintes en utilisant du multitasking coopératif ?

Au final, la problématique n’est pas spécifique à Rust, mais le langage permet de la résoudre en restant complètement memory safe, avec une absence de deadlocks, et des data races détectées à la compilation. Tout ça sur des microcontrôleurs d’un seul cœur, sans avoir à se reposer sur un garbage collector; soit exactement le type de points positifs  dont on souhaiterait bénéficier lorsque l’on travaille avec des microcontrôleurs !

Le blog post réalisé bien avant ce talk par son auteur vous donnera bien plus de détails que ce que je ne serais capable d’inclure dans ce résumé.

Mistakes to avoid when writing a wrapper around a C library

Rust étant régulièrement comparé à « du C, mais en plus safe », il est logique de se retrouver avec des besoins communs. Mais plutôt que de réimplémenter intégralement les bibliothèques bas niveau en C, un choix souvent fait est celui de wrapper ces bibliothèques C avec du Rust afin d’exposer une API plus safe sans pour autant réimplémenter toute la logique.

Ce talk présentait 9 « erreurs » à éviter lors du wrapping d’une bibliothèque C en Rust, et en voici le résumé :

Un talk plein de bon sens, qui nous rappelle les problèmes de sûreté du C et qui nous donne des pistes pour les éviter.

Conclusion sur ce talk : lire le Rustonomicon !

Rust In Rhymes

Que dire… Ce talk était un véritable show, entièrement en rimes, avec comme principal intérêt le fait de se décontracter après un slot bien technique.

Du coup, il n’y a pas grand chose à en résumer à l’écrit, et son appréciation dépendra grandement de votre humour ! Si vous souhaitez vous laisser tenter, le lien vers la vidéo est un peu plus haut.

Create Rust games easily

  • Speaker : Lisa – Product team @ Travis CI
  • Vidéo

Honnêtement, ce talk bien qu’intéressant m’a un peu déçu. Du live coding à base de copier/coller, trop rapide pour être réellement suivi, et avec un résultat final relativement minimal.

SHAR: Rust’s gamedev experience

Retour plus intéressant que le précédent… mais la partie jeu vidéo est un peu trop spécialisée pour que je sois à même de la critiquer; si vous voulez en savoir plus n’hésitez pas à jeter un œil à la vidéo !

Type-safe & high-perf distributed actor systems with Rust

 

LA surprise de cette fin de journée. Concrètement, tout est dans le titre, et le talk était une énorme démonstration du résultat avec explications sur l’implémentation. Globalement : création d’un simulateur de ville à base d’Acteurs distribués, en Rust, avec des performances vraiment impressionnantes.

Pour être honête, je n’ai pas pris énormément de notes tellement le talk était passionnant. Je vous invite cependant à en regarder la vidéo dont le lien est disponible ci-dessus et qui en vaut le détour ! La partie intéressante était plus la logique en elle-même que ce qui est fait en Rust ; le point à retenir sur Rust étant la possibilité d’implémenter un tel design d’acteurs distribués de manière vraiment propre et solide notamment grâce à la type-safety fournie par Rust, le tout avec un résultat performant.

Async I/O and Tokio

Ce talk est le seul ayant eu lieu le dimanche matin avant les ateliers.

Pour contexte, Alex Crichton est un des Core développeurs de Rust ayant été employé pendant 4 ans par Mozilla pour travailler sur le langage et son compilateur. C’est aussi un des principaux auteurs de Cargo, le gestionnaire de dépendances de Rust, ainsi qu’un des mainteneurs de la lib standard de Rust et de Tokio, LA bibliothèque pour des I/O asynchrones en Rust, sur laquelle cette présentation portait justement.

Ce talk, contrairement à ce qui pourrait sembler à la lecture du titre, n’est PAS une présentation de « comment faire de l’async avec Tokio », mais plutôt… « comment on implémente de l’async, en vrai ? ». En effet, c’est super d’avoir de l’asynchrone en tant qu’utilisateur, mais quels sont les mécanismes utilisés derrière ? Cette approche en fait donc définitivement le talk le plus intéressant de ce RustFest, ce qui en fait une très belle clôture mais aussi quelque chose de difficile à vraiment résumer.

Commençons par le début : qu’est ce que Tokio ?

  • Tokio = Mio + Futures
  • Mio = « Metal I/O », une bibliothèque d’I/O cross-platform en Rust
  • Futures = pensez aux « promises » de JS mais côté Rust (il s’agit en réalité du même pattern Future/Promise): il s’agit de sentinelles pour des valeurs « en cours de calcul ». En interne, une Future capture un état pour finir par produire une valeur. Les Futures dans Rust sont implémentées sous forme de Traits et sont composables.

Ceci étant posé, qu’est-ce que Tokio fait en réalité ? Un exemple d’utilisation abstrait serait le suivant :

  1. Utilisateur : « Je voudrais le contenu de https://blog.xebia.fr/ »
  2. Tokio : « OK, tiens, voilà un Future<Vec<u8>> »

Cette Future contiendra alors le résultat lorsque le contenu aura été récupéré et la promesse résolue : Tokio combine ici Mio et les Futures de Rust afin de nous proposer des I/O asynchrones d’un point de vue utilisateur, et ce pour une grande variété de moyens de communication : TCP, UDP, Sockets UNIX, Named pipes, signaux, HTTP, HTTP/2, websockets, …

Pour ce qui est de l’implémentation des cet asynchronisme, on aurait pu instinctivement penser à la réaliser sous forme de callbacks, mais ceux-ci présentent les inconvénients notoires de mener à du code peu clair, compliqué à maintenir  et de nécessiter une certaine « gymnastique » en cas de multithreading. C’est pourquoi Tokio nous propose plutôt une event loop, responsable de bloquer le thread courant et basée sur un concept de Task. Une Task est composée de plusieurs Futures, et devient l‘unité de concurrence, étant donc en ce sens très similaire aux green/lightweight threads.

Enfin, dernier point expliqué avec brio par Alex : comment savoir quand la Future est « résolue » et qu’en est-il du polling ?
Supposons que nous allions demander périodiquement à la Future (on Poll, donc) dans quel état elle se trouve :

  • Une valeur de retour de la Future à None (type Option) signifie « not ready »
  • Un retour de Some résout la Future

… mais du coup, en cas de None, quand rappeler poll ? Il a déjà été établi que dans le cadre de Tokio, les Futures appartiennent à une Task. Si la Future n’est pas prête… c’est cette Task qui doit réessayer plus tard, et donc savoir quand réessayer ! Une valeur de retour à None signifie donc implicitement et automatiquement « je te notifierai plus tard ».

En résumé : dans Tokio, TOUT est une Future. Ces Futures peuvent potentiellement nécessiter d’attendre des I/O, et le rôle de Tokio est donc de router les notifications d’I/O vers ces Tasks. Ces notifications ne sont autres que celles fournies par le kernel Linux lui même : « Le file descriptor 42 est prêt pour que tu ailles lire dessus » par exemple; et si vous avez suivi jusqu’ici, vous savez désormais que Tokio ira donc réveiller la Task en attente de l’I/O en question. Il n’existe visiblement pas de notifications d’I/O de ce genre sur Windows, et Tokio fait donc recours au polling en dernier recours dans ce cas, j’avoue ne pas avoir été vérifier.

Pour conclure, l’implémentation des Futures de Rust est vraiment passionnante, et l’event loop de Tokio se charge de « traduire » les notifications d’I/O du kernel en notifications pour les Tasks qui wrappent ces Futures. Au final, Tokio nous propose ici une manière élégante de faire des I/O asynchrones en Rust à base d’event loop et de Futures, nous évitant ainsi le légendaire callback hell.

Remarques diverses sur l’évènement lui-même

  • Le format des slots, 30min, était vraiment agréable
  • Les organisateurs proposaient 2 couleurs de tour-de-cou pour les badges : noir ou rouge, le noir signifiant « OK pour les photos » et le rouge « Je ne souhaite pas être pris en photo durant l’évènement ». Un grand bravo à eux pour avoir songé au côté vie privée, tant il est maintenant courant de photographier tout et tout le monde lors de conférences pour ensuite tout publier en ligne.
  • Toutes les vidéos sont disponibles sur la playlist YouTube officielle du RustFest

Conclusion

Cette conférence était vraiment une excellente vue d’ensemble sur ce qui se fait en Rust, avec des retours et des exemples de cas d’usage très variés, mais toujours avec le même point commun : le gros avantage de Rust, c’est la safety qu’il apporte ! Mention spéciale à Tokio, la bibliothèque d’I/O asynchrones en Rust, et au talk d’Alex Crichton à ce sujet que je vous invite à regarder.

L’exemple typique de cas d’utilisation parfait pour Rust semble être l’embarqué et les tâches vraiment bas niveau avec besoin de contrôle fin sur la mémoire tout en gardant une certaine solidité. Ce n’est bien sûr pas le seul, mais c’est en tout cas le plus représentatif. Par ailelurs, choisir Rust semble vraiment être un investissement sur la stabilité et la vie à long terme d’un projet.

Au final, ce RustFest confirme mon sentiment que Rust est vraiment approprié lorsque les besoins de safety et d’un langage complet se font sentir, là où Go, qui lui est souvent opposé, est, je trouve, plus approprié pour prototyper rapidement. Typiquement, je verrais très bien des orchestrateurs ou des composants système bas niveau en Rust ! En revanche, je n’ai vu aucun talk évoquant la construction d’API REST en Rust lors de cette conférence, bien que ce soit évidemment possible et facilité par des bibliothèques telles que Rocket. Si ce point vous intéresse, je vous invite à vous tourner vers la page « are we web yet? » de Rust

Dernier point, notez que le prochain RustFest se tiendra à Paris en 2018, et je vous y donne donc rendez-vous :)

Alexis "Horgix" Chotard

Alexis « Horgix » Chotard est DevOps chez Xebia et s’intéresse particulièrement à tout ce qui est infrastructure moderne et dynamique (infra-as-code, containérisation, automatisation, self-healing, déploiement continu, …).

Alexis est également formateur au sein de Xebia Training .

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *