The most dangerous phrase in the language is "We've always done it this way."
— Grace Hopper

Le processus RFC de TrueAsync

TrueAsync fait progresser la possibilité de modifier le cœur de PHP via le processus RFC.

RFC principal
Nouveau RFCDraft

Async Scheduler Hook API

Auteur : Edmond [HT]v0.1PHP 8.x

Un mécanisme d'activation de l'exécution concurrente au niveau du cœur de PHP. Le cœur expose des hooks dédiés qui permettent de déporter l'implémentation de l'ordonnanceur dans une extension distincte, voire dans du code PHP.

Principes clés
  • Opt-in strict : aucun surcoût tant qu'aucun ordonnanceur n'est enregistré
  • Compatible avec Fiber : le code Fiber existant continue de fonctionner, et les fibers sont prises en charge par l'ordonnanceur
  • Continuation : un changement de contexte symétrique A→B bâti sur la machinerie de Fiber
  • Un point d'enregistrement unique : SchedulerHook::register() active la concurrence dans tout le moteur
  • Isolation du contexte par coroutine : contextes utilisateur et interne séparés
  • Liberté de l'écosystème : le cœur ne standardise que l'activation et l'interface de l'ordonnanceur, tandis que spawn() / await() / les canaux restent à la charge de l'implémentation
Lire le RFC sur GitHub
Motivation

Pourquoi PHP a besoin d'une asynchronie native

PHP est l'un des derniers langages majeurs à ne toujours pas disposer d'un support natif de l'exécution concurrente au niveau du langage. Python a asyncio, JavaScript repose sur une boucle d'événements, Go a les goroutines, Kotlin a les coroutines. PHP reste dans le paradigme « une requête, un processus », alors que la plupart des applications réelles passent l'essentiel de leur temps à attendre des E/S.

Le problème de la fragmentation

Aujourd'hui, l'asynchrone en PHP vit dans des extensions : Swoole, AMPHP, ReactPHP, chacune avec son propre écosystème et des API incompatibles.

  • Chaque extension réécrit ses propres pilotes MySQL / PostgreSQL / Redis
  • Une bibliothèque pour Swoole ne fonctionne pas avec AMPHP, et inversement
  • Impossible de rendre non bloquantes les fonctions du cœur (file_get_contents, curl_exec)
  • Une barrière d'entrée élevée : tout un écosystème distinct à apprendre

La solution : un hook dans le moteur

TrueAsync ajoute une couture standard pour la concurrence au niveau du moteur PHP.

  • Transparence : le code synchrone s'exécute dans des coroutines sans modification
  • Pas de fonctions colorées : aucun marquage async/await
  • Un standard unifié : une seule interface d'ordonnanceur dans le moteur pour chaque extension
  • Rétrocompatibilité : le code existant continue de fonctionner

Une application PHP typique (Laravel, Symfony, WordPress) passe 70 à 90 % de son temps à attendre des E/S. Avec les coroutines, ce temps d'inactivité est utilisé efficacement :

Scénario
Sans coroutines
Avec coroutines
3 requêtes BD de 20 ms chacune
60 ms
~22 ms
HTTP + BD + fichier
séquentiel
parallèle
10 appels d'API
10 × latence
~1 × latence
Scénarios pratiques
Serveurs web · FrankenPHP, RoadRunnerAPI Gateway · agrégation parallèleTâches d'arrière-plan · files concurrentesTemps réel · WebSockets, streaming
Historique

RFC précédents

Ces deux RFC décrivaient un modèle de concurrence complet intégré directement au cœur. La nouvelle approche s'appuie sur leurs idées, mais sort du cœur l'API destinée à l'utilisateur, ne conservant dans le moteur que le point d'attache de l'ordonnanceur.

RFC #1Draft

PHP True Async

Auteur : Edmond [HT]v1.7PHP 8.6+

Le RFC qui définit un modèle de concurrence pour PHP. Il décrit les coroutines, les fonctions spawn() / await() / suspend(), l'objet Coroutine, les interfaces Awaitable et Completable, l'annulation coopérative, l'intégration avec Fiber, la gestion des erreurs et le graceful shutdown.

Principes clés
  • Modifications minimales du code existant pour activer la concurrence
  • Les coroutines conservent l'illusion d'une exécution séquentielle
  • Bascule automatique des coroutines lors des opérations d'E/S
  • Annulation coopérative, « cancellable by design »
  • API C standard pour les extensions
Lire le RFC sur wiki.php.net
RFC #2Draft

Scope et concurrence structurée

Auteur : Edmond [HT]v1.0

Une extension du RFC True Async. Il introduit la classe Scope, qui lie la durée de vie des coroutines à la portée lexicale. Il décrit la hiérarchie des scopes, la propagation des erreurs, la politique des coroutines « zombies » et les sections critiques via protect().

Ce qu'il résout
  • Empêcher les fuites de coroutines au-delà du scope
  • Nettoyage automatique des ressources à la sortie du scope
  • Annulation hiérarchique : annuler le parent annule tous les enfants
  • Protection des sections critiques contre l'annulation
  • Détection des interblocages et du self-await
Lire le RFC sur wiki.php.net

Comment ces RFC sont liés

Le premier RFC définit des primitives de bas niveau : coroutines, fonctions de base et API C pour les extensions. Le second RFC ajoute la concurrence structurée : des mécanismes de gestion de groupes de coroutines qui rendent le code concurrent sûr et prévisible.

RFC #1: True Async
RFC #2: Scope
Niveau
Primitives
Gestion
Fournit
spawn(), await(), Coroutine
Scope, TaskGroup, protect()
Analogies
Go goroutines, Kotlin coroutines
Kotlin CoroutineScope, Python TaskGroup
Objectif
Exécuter du code concurrent
Gestion sûre du cycle de vie

Rejoignez la discussion

Les RFC sont discutés sur la liste de diffusion internals@lists.php.net et sur GitHub Discussions. Rejoignez aussi la conversation sur Discord.