Asynchronisme

Un programme est dit asynchrone quand il est capable d’avoir simultanément plusieurs opérations d’entrées/sorties en vol sans devoir bloquer un thread d’OS par entrée/sortie en cours. Cela requiert un support de l’OS, via des APIs telles que epoll() et io_uring sous Linux, kqueue() sous macOS et BSD, et les I/O Completion Ports sous Windows.

Mais le support d’OS n’est qu’un fondement nécessaire de l’asynchronisme. Le plus difficile est en réalité de fournir un modèle de programmation ergonomique par dessus ces APIs système.

Historiquement, la communauté Rust a tenté de résoudre ce problème avec une solution purement basée sur les bibliothèques externes. Mais il est rapidement apparu qu’un support direct du langage pourrait grandement améliorer l’ergonomie de la programmation asynchrone. Par ailleurs, il était tout aussi clair que l’écosystème de bibliothèques externes n’était pas assez mature pour qu’une intégration complète de l’asynchronisme au langage et à la bibliothèque standard ait du sens.

L’approche choisie fut donc d’intégrer au langage juste l’ensemble de fonctionnalités nécessaire pour obtenir les améliorations ergonomiques voulues, tout en laissant le gros du travail aux bibliothèques externes pré-existante.

Il en résulte une situation actuelle un peu complexe où pour comprendre l’asynchronisme en Rust, il faut comprendre à la fois des concepts au niveau du langage, de la bibliothèque standard et des bibliothèques externes. C’est pourquoi ce chapitre sera sans doute le plus difficile des chapitres applicatifs de ce cours… Mais je vais faire de mon mieux pour clarifier ça, un petit pas à la fois.