La programmation asynchrone... et les pates
-
Upload
francois-zaninotto -
Category
Technology
-
view
900 -
download
0
description
Transcript of La programmation asynchrone... et les pates
![Page 1: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/1.jpg)
LA PROGRAMMATION ASYNCHRONE ET LES PÂTES
François Zaninotto - @francoisz - marmelab.com
![Page 2: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/2.jpg)
PARLONS
CUISINE
![Page 3: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/3.jpg)
Pour 4 personnes Préparation et cuisson: 20 minutes Ingrédients: - 500g de spaghetti - 6 tomates bien mûres - 1 oignon - 1 carotte - 2 gousses d'ail - 1 branche de céleri - huile d'olive - sauge, romarin, basilic frais - sel et poivre - amour
Spaghetti à la tomate de Giuseppina Plat principal - Facile - Bon marché
![Page 4: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/4.jpg)
1. Faire bouillir une grande quantité d'eau (non salée) dans une casserole
2. Pendant ce temps, pelez les tomates et coupez-les grossièrement
3. Epluchez et émincez l'oignon, la carotte, l'ail et le céleri
4. Lorsque l'eau bout, salez-la, puis déposez les spaghettis en couronne
5. Faire chauffer l'huile d'olive dans une sauteuse. Mettez-y à brunir la deuxième gousse d'ail préalablement épluchée.
6. Retirez la gousse d'ail, puis versez le mirepoix (mélange de légumes) et faites revenir à feu vif
7. Ajoutez les tomates, les herbes, salez et poivrez copieusement. Faites chauffer à feu moyen pendant 5 minutes
8. Goûtez régulièrement les spaghettis. Lorsqu'ils sont cuits al dente, égouttez-les puis déposez-les dans un plat chaud.
9. Versez la sauce tomate immédiatement sur les pâtes fumantes. Ajoutez le basilic grossièrement découpé.
10.Servez avec du parmesan rapé et un bon Chianti Classico, et régalez-vous
Spaghetti à la tomate de Giuseppina Plat principal - Facile - Bon marché
![Page 5: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/5.jpg)
MAINTENANT LE CHEF C’EST
PHP
![Page 6: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/6.jpg)
// time is 0 $pastaPan = new Pan(); $water = new Water(); $pastaPan-‐>fill($water); $pastaPan-‐>warm($duration = 10); // now time is 10 $pastaPan-‐>fill(new Spaghetti()); $pastaPan-‐>warm($duration = 8); // now time is 18 $pastaPan-‐>remove($water); !$saucePan = new Pan(); $saucePan-‐>fill(new OliveOil()); $saucePan-‐>warm($duration = 2); // now time is 20 $saucePan-‐>fill(MirepoixFactory::create($withGarlic = true)); $saucePan-‐>warm($duration = 5); // now time is 25 $saucePan-‐>fill(TomatoFactory::create()); $saucepan-‐>warm($duration = 4); // now time is 29 !$plate = new Plate(); $plate-‐>addContentsOf($pastaPan); $plate-‐>addContentsOf($saucePan); $plate-‐>serve('Régalez-‐vous');
![Page 7: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/7.jpg)
LES 3 GRANDS TABOUS DU DEVELOPPEUR
UTILISER eval()
![Page 8: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/8.jpg)
INJECTER UN CONTENEUR D’INJECTION DE DÉPENDANCE
LES 3 GRANDS TABOUS DU DEVELOPPEUR
![Page 9: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/9.jpg)
SERVIR DES PÂTES FROIDES
LES 3 GRANDS TABOUS DU DEVELOPPEUR
![Page 10: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/10.jpg)
2/10 NOTE DES INVITÉS
![Page 11: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/11.jpg)
EVENTLOOP À LA RESCOUSSE
![Page 12: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/12.jpg)
class EventLoop { protected $tick = 0; protected $callbacksForTick = array(); ! public function executeLater($delay, $callback) { $this-‐>callbacksForTick[$this-‐>tick + $delay] []= $callback; } public function start() { while ($this-‐>callbacksForTick) { $this-‐>tick++; $this-‐>executeCallbacks(); } } public function executeCallbacks() { echo "tic-‐tac : " . $this-‐>tick . "\n"; if (!isset($this-‐>callbacksForTick[$this-‐>tick])) { return; // no callback to execute } foreach ($this-‐>callbacksForTick[$this-‐>tick] as $callback) { call_user_func($callback); } // clean up unset($this-‐>callbacksForTick[$this-‐>tick]); } }
![Page 13: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/13.jpg)
LA CASSEROLE
ASYNCHRONE
![Page 14: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/14.jpg)
class AsynchronousPan extends Pan { protected $eventLoop; public function __construct(EventLoop $eventLoop) { $this-‐>eventLoop = $eventLoop; } public function warm($duration, $callback) { $this-‐>eventLoop-‐>executeLater($duration, $callback); } }
![Page 15: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/15.jpg)
$eventLoop = new EventLoop(); !
$pan = new AsynchronousPan($eventLoop); $pan-‐>warm(10, function() { echo "Régalez-‐vous\n"; }); !
echo "Ca chauffe !\n"; !
$eventLoop-‐>start();
![Page 16: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/16.jpg)
DÉMONSTRATION
![Page 17: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/17.jpg)
Ca chauffe ! tic-‐tac : 1 tic-‐tac : 2 tic-‐tac : 3 tic-‐tac : 4 tic-‐tac : 5 tic-‐tac : 6 tic-‐tac : 7 tic-‐tac : 8 tic-‐tac : 9 tic-‐tac : 10 Régalez-‐vous
![Page 18: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/18.jpg)
LES SPAGHETTI
ASYNCHRONES
![Page 19: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/19.jpg)
$eventLoop = new EventLoop(); !
$plate = new Plate(); !
// pasta $pastaPan = new AsynchronousPan($eventLoop); $water = new Water(); $pastaPan-‐>fill($water); echo "pastaPan: Allumage\n"; $pastaPan-‐>warm($duration = 10, function() use ($pastaPan, $plate, $water) { echo "pastaPan: L'eau bout\n"; $pastaPan-‐>fill(new Spaghetti()); echo "pastaPan: Lancement de la cuisson des spaghettis\n"; $pastaPan-‐>warm($duration = 8, function() use ($pastaPan, $plate, $water){ echo "pastaPan: Les spaghettis sont prêts\n"; $pastaPan-‐>remove($water); $plate-‐>addContentsOf($pastaPan); }); }); ../..
![Page 20: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/20.jpg)
../.. // sauce $eventLoop-‐>executeLater($delay = 7, function() use ($plate, $eventLoop) { $saucePan = new AsynchronousPan($eventLoop); $saucePan-‐>fill(new OliveOil()); echo "saucePan: L'huile chauffe\n"; $saucePan-‐>warm($duration = 2, function() use($saucePan, $plate) { echo "saucePan: L'huile est chaude\n"; $saucePan-‐>fill(MirepoixFactory::create($withGarlic = true)); echo "saucePan: Lancement de la cuisson du mirepoix\n"; $saucePan-‐>warm($duration = 5, function() use($saucePan, $plate) { echo "saucePan: Le mirepoix est prêt pour la tomate\n"; $saucePan-‐>fill(TomatoFactory::create()); echo "saucePan: Lancement de la cuisson de la tomate\n"; $saucePan-‐>warm($duration = 4, function() use($saucePan, $plate) { echo "saucePan: La sauce est prête\n"; $plate-‐>addContentsOf($saucePan); }); }); }); }); !$eventLoop-‐>start(); $plate-‐>serve('Régalez-‐vous');
![Page 21: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/21.jpg)
SÉQUENTIALITÉSy
nchro
ne
Asynchrone
![Page 22: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/22.jpg)
pastaPan: Allumage tic-‐tac : 1 ... tic-‐tac : 7 saucePan: L'huile chauffe tic-‐tac : 8 tic-‐tac : 9 saucePan: L'huile est chaude saucePan: Lancement de la cuisson du mirepoix tic-‐tac : 10 pastaPan: L'eau bout pastaPan: Lancement de la cuisson des spaghettis tic-‐tac : 11 .... tic-‐tac : 14 saucePan: Le mirepoix est prêt pour la tomate saucePan: Lancement de la cuisson de la tomate tic-‐tac : 15 ... tic-‐tac : 18 pastaPan: Les spaghettis sont prêts saucePan: La sauce est prête Régalez-‐vous
![Page 23: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/23.jpg)
SCRIPT SYNCHRONE
29 MINUTES
![Page 24: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/24.jpg)
SCRIPT ASYNCHRONE
18 MINUTES
![Page 25: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/25.jpg)
7/10 NOTE DES INVITÉS
![Page 26: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/26.jpg)
class EventLoop { protected $tick = 0; protected $callbacksForTick = array(); ! public function executeLater($delay, $callback) { $this-‐>callbacksForTick[$this-‐>tick + $delay] []= $callback; } public function start() { while ($this-‐>callbacksForTick) { $this-‐>tick++; $this-‐>executeCallbacks(); } } public function executeCallbacks() { echo "tic-‐tac : " . $this-‐>tick . "\n"; if (!isset($this-‐>callbacksForTick[$this-‐>tick])) { return; // no callback to execute } foreach ($this-‐>callbacksForTick[$this-‐>tick] as $callback) { call_user_func($callback); } // clean up unset($this-‐>callbacksForTick[$this-‐>tick]); } }
![Page 27: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/27.jpg)
// ... $eventLoop-‐>start(); !
// Never executed $plate-‐>serve('Régalez-‐vous');
![Page 28: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/28.jpg)
RESYNCHRONISER L’ASYNCHRONE
![Page 29: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/29.jpg)
class PlateOfSpaghettiWithSauce extends Plate { protected $hasSpaghetti = false; protected $hasSauce = false; public function addContentsOf(Pan $pan) { parent::addContentsOf($pan); if ($pan-‐>contains('Spaghetti')) { $this-‐>hasSpaghetti = true; } if ($pan-‐>contains('Tomato')) { $this-‐>hasSauce = true; } if ($this-‐>hasSpaghetti && $this-‐>hasSauce) { $this-‐>serve('Régalez-‐vous'); } } }
![Page 30: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/30.jpg)
../.. // sauce $eventLoop-‐>executeLater($delay = 7, function() use ($plate, $eventLoop) { $saucePan = new AsynchronousPan($eventLoop); $saucePan-‐>fill(new OliveOil()); echo "saucePan: L'huile chauffe\n"; $saucePan-‐>warm($duration = 2, function() use($saucePan, $plate) { echo "saucePan: L'huile est chaude\n"; $saucePan-‐>fill(MirepoixFactory::create($withGarlic = true)); echo "saucePan: Lancement de la cuisson du mirepoix\n"; $saucePan-‐>warm($duration = 5, function() use($saucePan, $plate) { echo "saucePan: Le mirepoix est prêt pour la tomate\n"; $saucePan-‐>fill(TomatoFactory::create()); echo "saucePan: Lancement de la cuisson de la tomate\n"; $saucePan-‐>warm($duration = 4, function() use($saucePan, $plate) { echo "saucePan: La sauce est prête\n"; $plate-‐>addContentsOf($saucePan); }); }); }); }); !$eventLoop-‐>start(); $plate-‐>serve('Régalez-‐vous');
![Page 31: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/31.jpg)
DÉMÊLER LE CODE
SPAGHETTI
![Page 32: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/32.jpg)
$saucePan = new AsynchronousPan($eventLoop); $eventLoop-‐>executeLater($delay = 7, function() { call_user_func($warmSaucePan); }); $warmSaucePan = function() use ($saucePan) { $saucePan-‐>fill(new OliveOil()); echo "saucePan: L'huile chauffe\n"; $saucePan-‐>warm($duration = 2, $cookMirepoix); }; $cookMirepoix = function() use ($saucePan) { echo "saucePan: L'huile est chaude\n"; $saucePan-‐>fill(MirepoixFactory::create($withGarlic = true)); echo "saucePan: Lancement de la cuisson du mirepoix\n"; $saucePan-‐>warm($duration = 5, $cookTomato); }; $cookTomato = function() use ($saucePan) { echo "saucePan: Le mirepoix est prêt pour la tomate\n"; $saucePan-‐>fill(TomatoFactory::create()); echo "saucePan: Lancement de la cuisson de la tomate\n"; $saucePan-‐>warm($duration = 4, $serveSauce); }; $serveSauce = function() use ($saucePan, $plate) { echo "saucePan: La sauce est prête\n"; $plate-‐>addContentsOf($saucePan); };
![Page 33: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/33.jpg)
$saucePan = new AsynchronousPan($eventLoop); $serveSauce = function() use ($saucePan, $plate) { echo "saucePan: La sauce est prête\n"; $plate-‐>addContentsOf($saucePan); }; $cookTomato = function() use ($saucePan, $serveSauce) { echo "saucePan: Le mirepoix est prêt pour la tomate\n"; $saucePan-‐>fill(TomatoFactory::create()); echo "saucePan: Lancement de la cuisson de la tomate\n"; $saucePan-‐>warm($duration = 4, $serveSauce); }; $cookMirepoix = function() use ($saucePan, $cookTomato) { echo "saucePan: L'huile est chaude\n"; $saucePan-‐>fill(MirepoixFactory::create($withGarlic = true)); echo "saucePan: Lancement de la cuisson du mirepoix\n"; $saucePan-‐>warm($duration = 5, $cookTomato); }; $warmSaucePan = function() use ($saucePan, $cookMirepoix) { $saucePan-‐>fill(new OliveOil()); echo "saucePan: L'huile chauffe\n"; $saucePan-‐>warm($duration = 2, $cookMirepoix); }; $eventLoop-‐>executeLater($delay = 7, function() use ($warmSaucePan) { call_user_func($warmSaucePan); });
![Page 34: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/34.jpg)
$saucePan = new AsynchronousPan($eventLoop); $warmSaucePan = function($callback) use ($saucePan) { $saucePan-‐>fill(new OliveOil()); echo "saucePan: L'huile chauffe\n"; $saucePan-‐>warm($duration = 2, $callback); }; $cookMirepoix = function($callback) use ($saucePan) { echo "saucePan: L'huile est chaude\n"; $saucePan-‐>fill(MirepoixFactory::create($withGarlic = true)); echo "saucePan: Lancement de la cuisson du mirepoix\n"; $saucePan-‐>warm($duration = 5, $callback); }; $cookTomato = function($callback) use ($saucePan) { echo "saucePan: Le mirepoix est prêt pour la tomate\n"; $saucePan-‐>fill(TomatoFactory::create()); echo "saucePan: Lancement de la cuisson de la tomate\n"; $saucePan-‐>warm($duration = 4, $callback); }; $serveSauce = function() use ($saucePan, $plate) { echo "saucePan: La sauce est prête\n"; $plate-‐>addContentsOf($saucePan); }; $eventLoop-‐>executeLater($delay = 7, function() use ($plate, $eventLoop) { Async::waterfall( array($warmSaucePan, $cookMirepoix, $cookTomato), $serveSauce ); });
![Page 35: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/35.jpg)
class Async { public static function waterfall($tasks, $callback = null) { $taskCallback = function () use (&$next) { call_user_func_array($next, func_get_args()); }; $done = function () use ($callback) { if ($callback) { call_user_func_array($callback, func_get_args()); } }; $next = function () use (&$tasks, $taskCallback, $done) { if (0 === count($tasks)) { call_user_func_array($done, func_get_args()); return; } ! $task = array_shift($tasks); $args = array_merge(func_get_args(), array($taskCallback)); call_user_func_array($task, $args); }; $next(); } }
Source: https://github.com/reactphp/async/blob/master/src/React/Async/Util.php#L81
![Page 36: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/36.jpg)
EN ASYNCHRONE PAS DE RETURN
![Page 37: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/37.jpg)
// prototype synchronous function $cook = function($ingredient) use ($saucePan) { $saucePan-‐>fill($ingredient); $saucePan-‐>warm(5); return 'chaud devant'; }; !
!
$message = $cook(MirepoixFactory::create()); echo $message, "\n";
![Page 38: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/38.jpg)
// prototype asynchronous function $cook = function($ingredient, $callback) use ($saucePan) { $saucePan-‐>fill($ingredient); $saucePan-‐>warm(5, function() { $callback('chaud devant'); }); }; !
$cook(MirepoixFactory::create(), function($message) { echo $message, "\n"; });
![Page 39: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/39.jpg)
EN ASYNCHRONE PAS DE TRY/CATCH
![Page 40: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/40.jpg)
$cook = function($ingredient, $callback) use ($saucePan) { $saucePan-‐>fill($ingredient); $saucePan-‐>warm(5, function() { $isSummer = in_array(date('m'), array(6, 7, 8)): if ($saucePan-‐>contains('Tomato') && !$isSummer) { throw new OutOfBoundsException('On ne fait de la bonne sauce tomate qu\'en été'); } $callback('chaud devant !'); }); }; !
try { $cook(MirepoixFactory::create(), function($message) { echo $message, "\n"; }); } catch (OutOfBoundsException $e) { echo "Echec de la recette\n"; }
![Page 41: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/41.jpg)
$cook = function($ingredient, $callback) use ($saucePan) { $saucePan-‐>fill($ingredient); $saucePan-‐>warm(5, function() { $isSummer = in_array(date('m'), array(6, 7, 8)): if ($saucePan-‐>contains('Tomato') && !$isSummer) { return callback(new OutOfBoundsException('On ne fait de la bonne sauce tomate qu\'en ete')); } $callback(null, 'chaud devant !'); }); }; !
$cook(MirepoixFactory::create(), function($error, $message) { if ($error instanceOf OutOfBoundsException) { echo "Echec de la recette\n"; return; } echo $message, "\n"; });
![Page 42: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/42.jpg)
DU CODE RÉUTILISABLE
ROBUSTE UN PLAT
CHAUD
![Page 43: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/43.jpg)
VICTOIRE !
![Page 44: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/44.jpg)
10/10 NOTE DES INVITÉS
![Page 45: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/45.jpg)
IL N’Y A TOUJOURS
QU’UN SEUL CHEF
![Page 46: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/46.jpg)
PROGRAMMATION NON
PARALLELE
![Page 47: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/47.jpg)
PAS DE TEMPS PERDU A ATTENDRE LA RÉPONSE D’UN AUTRE
![Page 48: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/48.jpg)
Operation CPU cycles L1 .................. 3 L2 .................. 14 RAM ................. 250 Disk ................ 41,000,000 Network ............. 240,000,000
LATENCE I/O
![Page 49: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/49.jpg)
L1 cache reference ......................... 0.5 ns L2 cache reference ........................... 7 ns Main memory reference ...................... 100 ns Compress 1K bytes with Zippy ............. 3,000 ns = 3 µs Send 2K bytes over 1 Gbps network ....... 20,000 ns = 20 µs SSD random read ........................ 150,000 ns = 150 µs Read 1 MB sequentially from memory ..... 250,000 ns = 250 µs Round trip within same datacenter ...... 500,000 ns = 0.5 ms Read 1 MB sequentially from SSD* ..... 1,000,000 ns = 1 ms Disk seek ........................... 10,000,000 ns = 10 ms Read 1 MB sequentially from disk .... 20,000,000 ns = 20 ms Send packet CA-‐>Netherlands-‐>CA .... 150,000,000 ns = 150 ms
Source: http://www.cs.cornell.edu/projects/ladis2009/talks/dean-keynote-ladis2009.pdf
![Page 50: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/50.jpg)
I/O = ATTENTE ETABLISSEMENT CONNEXION SÉCURISÉE
RÉCEPTION REQUÊTE HTTP REQUÊTE BASE DE DONNÉES
LECTURE VALEUR DANS MEMCACHE LECTURE DE FICHIER SUR DISQUE
APPEL À UNE API REST ENVOI MESSAGE À UN AMQP
ENVOI RÉPONSE HTTP
![Page 51: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/51.jpg)
90% DU TEMPS DE RÉPONSE
D’UNE REQUÊTE HTTP EST PASSÉ À ATTENDRE UNE I/O
![Page 52: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/52.jpg)
GET /favicon.ico
Routing Lancement de l’ordre de chargement du fichier
Déplacement de la tête de lecture Transfert des données du disque en mémoire
Envoi de la réponse HTTPTraitement
Attente Fin de la requête
Construction de la réponse HTTP
Process serveur
![Page 53: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/53.jpg)
UN SERVEUR WEB PASSE SON TEMPS A SE TOURNER
LES POUCES
![Page 54: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/54.jpg)
POUR MIEUX UTILISER LE CPU
ON MULTIPLIE LES PROCESS LES THREADS
ET DONC LA CONSO MÉMOIRE
![Page 55: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/55.jpg)
MaxClients 50
![Page 56: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/56.jpg)
UN AUTRE MONDE
EST POSSIBLE
![Page 57: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/57.jpg)
GET /favicon.ico
Traitement
Attente
Process serveur
I/O disque asynchrone
Transfert des données du disque en mémoire
Envoi de la réponse HTTP
I/O réseau asynchrone
![Page 58: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/58.jpg)
LIBEL EVENT LOOP
LIBEIO ASYNCHRONOUS I/O
LIBUV MULTI-PLATFORM ABSTRACTION LAYER
![Page 59: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/59.jpg)
GET /favicon.icoGET /js/jquery.jsGET /css/main.css
![Page 60: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/60.jpg)
COMMENT FAIRE DES I/O ASYNCHRONES
EN PHP ?
![Page 61: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/61.jpg)
Event-‐driven, non-‐blocking I/O with PHP.
![Page 62: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/62.jpg)
PHP & PROCESS PERSISTENTS
PAS BON MÉNAGE
![Page 63: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/63.jpg)
PHP N’A PAS DE FONCTIONS D’I/O DISQUE ASYNCHRONES
PECL/LIBIO
![Page 64: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/64.jpg)
TANT QU’À INSTALLER UN BINAIRE
AUTANT EN PRENDRE UN
STABLE POPULAIRE
![Page 65: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/65.jpg)
TANT QU’À REPOSER SUR UNE EVENT LOOP
AUTANT UTILISER UN LANGAGE
ÉVÈNEMENTIEL
![Page 66: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/66.jpg)
TANT QU’À ABUSER DES FONCTIONS ANONYMES
AUTANT UTILISER UN LANGAGE
FONCTIONNEL
![Page 67: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/67.jpg)
![Page 68: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/68.jpg)
var fs = require('fs'); fs.unlink('/tmp/hello', function (err) { if (err) throw err; console.log('successfully deleted /tmp/hello'); }); // more code console.log('deletion script');
![Page 69: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/69.jpg)
plate = new Plate(); pastaPan = new AsynchronousPan(eventLoop); water = new Water(); pastaPan.fill(water); console.log('pastaPan: Starting to boil water'); pastaPan.warm(duration = 10, function() { console.log('pastaPan: Water is boiling'); pastaPan.fill(new Spaghetti()); console.log('pastaPan: Starting to boil spaghetti'); pastaPan.warm(duration = 8, function() { console.log('pastaPan: Spaghetti is ready'); pastaPan.remove(water); plate.addContentsOf(pastaPan); }); });
![Page 70: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/70.jpg)
$plate = new Plate(); $pastaPan = new AsynchronousPan($eventLoop); $water = new Water(); $pastaPan-‐>fill($water); echo "pastaPan: Starting to boil water\n"; $pastaPan-‐>warm($duration = 10, function() use ($pastaPan, $plate, $water) { echo "pastaPan: Water is boiling\n"; $pastaPan-‐>fill(new Spaghetti()); echo "pastaPan: Starting to boil spaghetti\n"; $pastaPan-‐>warm($duration = 8, function() use ($pastaPan, $plate, $water) { echo "pastaPan: Spaghetti is ready\n"; $pastaPan-‐>remove($water); $plate-‐>addContentsOf($pastaPan); }); });
![Page 71: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/71.jpg)
I/O ASYNCHRONES UN SEUL CHEF
DES CALLBACKS PLUS DE CONCURRENCE
MOINS DE CONSOL MÉMOIRE PAS POSSIBLE EN PHP, NATIF EN NODE.JS
PAS DE RETURN, PAS DE TRY/CATCH
![Page 72: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/72.jpg)
DES PÂTES CHAUDES
![Page 73: La programmation asynchrone... et les pates](https://reader033.fdocuments.net/reader033/viewer/2022042601/548fedcbb4795927058b4fd8/html5/thumbnails/73.jpg)
MERCI
François Zaninotto - @francoisz - marmelab.com github.com/fzaninotto - github.com/marmelab