Lecture 4 minutes
Chaque année apporte une nouvelle version majeure ou mineure de PHP, et cette année 2021 n'a pas été différente. Sorti fin Novembre, PHP 8.1 a été livrée avec son lot de fonctionnalités et obsolescences. Lors du forum PHP 2021, Benoit VIGUIER, Principal Engineer chez Bedrock, nous dépeignait une des nouveautés apportées par cette version : les Fibers.
Selon la documentation, à moins que vous n'ayez une raison très étrange de les utiliser directement, vous n'aurez jamais à interagir avec les Fibers. Certains frameworks de haut niveau (comme Symfony et Laravel, entre autres) prendront un certain temps pour les aborder et créer un ensemble d'outils avec lesquels travailler du point de vue du développeur. D’autres frameworks de bas niveau, comme amphp et ReactPHP, ont déjà commencé à implémenter les Fibers dans leurs dernières versions de développement.
Que sont les Fibers ?
Pendant sa présentation, Benoit VIGUIER nous explique ce que sont les Fibers. Le concept de Fiber fait essentiellement référence aux coroutines. Celles-ci semblent fonctionner en parallèle mais sont finalement gérées par le runtime lui-même plutôt qu'en le poussant directement vers le CPU.
Le principe est simple : laisser l'ordinateur faire deux choses ou plus en même temps, et attendre que tout soit terminé. Il est donc possible de créer des fonctions similaires à await et async pour rendre la programmation asynchrone moins intrusive dans notre code et permettre la compatibilité avec les frameworks existants.
Pour rentrer dans le détail, une Fiber est une classe qui reçoit un callable, et dont l'exécution peut être interrompue grâce à une fonction suspend puis peut ensuite être redémarrée grâce à une fonction resume.
Comment ça marche ?
La classe Fiber comporte plusieurs méthodes :
- Des méthodes de Status qui permettent de savoir dans quel état est une Fiber ("Started", "Running", "Terminated",…)
- Des méthodes d'Interruption qui permettent d'interrompre ou de reprendre l'exécution dans une Fiber
- Une méthode statique Current qui permet de savoir quelle est la Fiber actuellement en cours d'exécution
À quoi ça sert ?
Imaginez que vous souhaitiez envoyer trois requêtes HTTP et traiter leur résultat combiné. La manière synchrone de le faire est d'envoyer le premier, d'attendre la réponse, puis d'envoyer le second, d'attendre, etc.
Représentons un tel déroulement de programme avec un graphique aussi simple que possible. Vous devez lire ce tableau de haut en bas, et le temps progresse au fur et à mesure que vous descendez. Chaque couleur représente une requête HTTP. Les pièces colorées de chaque requête représentent le code PHP en cours d'exécution, tandis que les blocs transparents représentent les temps d'attente :
Flux d'exécution synchrone :
La requête doit être envoyée sur le réseau, le serveur doit la traiter et la renvoyer. Ce n'est que lorsque la réponse arrive que nous pouvons continuer l’exécution.
Flux d’exécution en utilisant Fibers :
La demande est envoyée mais il n’y a pas d’attente . La demande suivante est directement envoyée, suivie des autres. Ce n'est qu'alors que nous attendons que toutes les demandes soient envoyées, en vérifiant périodiquement si l'une de nos demandes est déjà terminée. Si tel est le cas, nous pouvons la traiter immédiatement.
Cela nous amène cependant à la question : quels sont les avantages des Fibers par rapport à ce que nous pouvons déjà faire avec des générateurs ? Eh bien, la RFC l'explique ainsi :
Contrairement aux générateurs sans pile, chaque Fiber a sa propre pile d'appels, ce qui leur permet d'être mis en pause dans des appels de fonction profondément imbriqués. Une fonction déclarant un point d'interruption (c'est-à-dire appelant Fiber::suspend()) n'a pas besoin de changer son type de retour, contrairement à une fonction utilisant yield qui doit retourner une instance de Generator.
Les Fibers peuvent être suspendues dans n'importe quel appel de fonction, y compris ceux appelés depuis la VM PHP, tels que les fonctions fournies à array_map ou les méthodes appelées par foreach sur un objet Iterator.
Benoit VIGUIER précise, lors de la fin de sa présentation, qu’il est clair que les Fibers sont une amélioration significative, à la fois en termes de syntaxe et de flexibilité, mais qu’il manque encore beaucoup de fonctionnalités pour que le PHP asynchrone devienne courant sans la surcharge des frameworks, et les Fibers sont un bon pas dans cette direction.
Le sujet vous interesse ? (re)découvrez en vidéo la conférence de Benoit VIGUIER