SlideShare a Scribd company logo
Exploring Async PHP
@dantleech
Symfony Live Berlin 27th
September 2019
MySQL
SLOW
HTTP Requests
SLOW
REDIS
SLOW
Elastic
SLOW
TL;DR;
SLOW
Network I/O
Array TCP Connect TCP Read HTTP GET (local) HTTP GET (network) HTP GET (internet)
3 432 595 1,084
9,221
94,348
Product Import
News Website
DEPENDENCIES
Operations with no un-resolved dependencies
can be parallezied
(Application)
User Widget
Menu
Nodes
RSS Feed
Category
Widget
URL 1 URL 2 URL ...
What can we make with
an Async PHP?
Concurrrent I/O
HTTP Requests
Database Queries
Child Processes
HTTP Server
Web Socket Servers
Long Running Processes...
Web Crawlers!
Development tools
Daemons
Exploring Async PHP (SF Live Berlin 2019)
STREAMS
Streams
•
Abstraction layer for resources: file://, http://,
tcp://, etc
•
Can be read from and written to incrementally
•
Can be non blocking
1: File get contents
<?php
echo file_get_contents('http://localhost:8080?sleep=1');
Exploring Async PHP (SF Live Berlin 2019)
2: Stream socket client
<?php
$stream = stream_socket_client('tcp://localhost:8080');
fwrite($stream, "GET /?sleep=1 HTTP/1.0rnrn");
echo stream_get_contents($stream);
Exploring Async PHP (SF Live Berlin 2019)
3: Stream set blocking
<?php
$stream = stream_socket_client('tcp://localhost:8080');
stream_set_blocking($stream, false);
echo stream_get_contents($read[0]);
die(‘Hello World’);
Exploring Async PHP (SF Live Berlin 2019)
3: Stream set blocking
<?php
$stream = stream_socket_client('tcp://localhost:8080');
stream_set_blocking($stream, false);
fwrite($stream, "GET /?sleep=1 HTTP/1.0rnrn");
$write = $except = null;
$read = [ $stream ];
stream_select($read, $write, $except, null);
echo stream_get_contents($read[0]);
Exploring Async PHP (SF Live Berlin 2019)
4: Multiple Requests<?php
$stream1 = create_non_blocking_get('tcp://localhost:8080', ‘/?sleep=1’);
$stream2 = create_non_blocking_get('tcp://localhost:8080', ‘/?sleep=1’);
$await = [ $stream1, $stream2 ];
$write = $except = null;
while ($await) {
$read = $await;
stream_select($read, $write, $except, null);
foreach ($read as $stream) {
echo stream_get_contents($stream) . PHP_EOL;
unset($await[array_search($stream, $await)]);
fclose($stream);
}
}
Exploring Async PHP (SF Live Berlin 2019)
Amphp
•
Born 2013
•
Redis Client
•
MySQL Client
•
Promises
•
Coroutines
•
Event Loop
EVENT LOOP
Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)
Event Loop
<?php
$stream = create_non_blocking_get('tcp://localhost:8080', ‘/?sleep=1’);
Loop::onReadable($stream, function ($watcherId, $stream) {
echo stream_get_contents($stream);
});
Loop::run();
PROMISES
No Promise
<?php
http_request("http://example/.com/foobar", function ($response) {
echo $response->getStatusCode();
});
Promise
<?php
http_request("http://example/.com/foobar")->onResolve(function ($failure, $response) {
echo $response->getStatusCode();
});
Multiple Promise
<?php
$promise1 = http_request("http://example/.com/foobar");
$promise2 = http_request("http://example/.com/barfoo");
$results = wait ( all ($promise1, $promise2));
echo $promise1->getStatusCode();
echo $promise2->getStatusCode();
You can yield a promise ...
COROUTINES
CO-
ROUTINE
CO-
ROUTINE
CO-
ROUTINE
CO-
ROUTINE
Event Loop (scheduler)
Coroutine Example
<?php
call(function () {
$response = yield http_request("http://example/.com/foobar");
echo $reponse->getStatusCode();
$body = yield $response->getBody();
echo $body;
});
call(function () {
$response = yield http_request("http://example/.com/barfoo");
});
LET’S
BUILD A CI
SYSTEM
<?php
class Runner
{
public function __construct(Workspace $workspace, array $scripts) { /** ... */ }
public function run(): int { /** ... */ }
private function runRepos(): Promise { /** ... */ }
private function runRepo($repoUrl, $scripts, int $color): Promise { /** ... */ }
private function runCommand(string $command, $cwd, int $color): Promise { /** ... */ }
private function display(ProcessInputStream $processInputStream, $color) { /** ... */ }
}
$runner = new Runner(
new Workspace(__DIR__ . '/../Workspace'),
[
'git@github.com:dantleech/fink' => [
'composer install --prefer-dist',
'vendor/bin/phpunit',
'vendor/bin/phpstan analyse --level=7',
],
'git@github.com:phpactor/path-finder' => [
'composer install',
'./vendor/bin/phpunit',
'vendor/bin/phpstan analyse --level=7',
]
]
);
$aggregateExitCode = $runner->run();
sprintf('Aggregate exit code: %s', $aggregateExitCode) . PHP_EOL;
exit($aggregateExitCode);
class Runner
{
/**
* @var array
*/
private $scripts;
/**
* @var Workspace
*/
private $workspace;
public function __construct(Workspace $workspace, array $scripts)
{
$this->scripts = $scripts;
$this->workspace = $workspace;
}
// ...
class Runner
{
// ...
public function run(): int
{
$this->workspace->reset();
$exitCodes = wait ( $this->runRepos());
return array_sum($exitCodes);
}
class Runner
{
// ...
private function runRepos(): Promise
{
$exitCodePromises = [];
$color = 31;
foreach ($this->scripts as $repoUrl => $scripts) {
$color++;
$exitCodePromises[] = $this->runRepo($repoUrl, $scripts, $color);
}
return all($exitCodePromises);
}
class Runner
{
// ...
private function runRepo($repoUrl, $scripts, int $color): Promise
{
return call(function () use ($repoUrl, $scripts, $color) {
$repoPath = $this->workspace->path(basename($repoUrl));
$exitCode = yield $this->runCommand(sprintf(
'git clone %s %s',
$repoUrl,
$repoPath,
), $this->workspace->path('/'), $color);
foreach ($scripts as $script) {
$exitCode += yield $this->runCommand($script, $repoPath, $color);
}
return $exitCode;
});
}
class Runner
{
// ...
private function runCommand(string $command, string $cwd, int $color): Promise
{
return call(function () use ($command, $cwd, $color) {
$process = new Process($command, $cwd);
$pid = yield $process->start();
$this->display($process->getStdout(), $color);
$this->display($process->getStderr(), $color);
$exitCode = yield $process->join();
return $exitCode;
});
}
class Runner
{
// ...
private function display(ProcessInputStream $processInputStream, $color): void
{
asyncCall(function () use ($processInputStream, $color) {
while (null !== $chunk = yield $processInputStream->read()) {
echo sprintf("033[%sm%s033[0m", $color, $chunk);
};
});
}
Exploring Async PHP (SF Live Berlin 2019)
Other Frameworks
React PHP
•
Born 2012
•
Redis Client
•
MySQL Client
•
Promises
•
Event Emitter
•
Event Loop
Exploring Async PHP (SF Live Berlin 2019)
Swoole
•
Born 2012
•
Redis Client
•
MySQL Client
•
Promises
•
Coroutines
•
Event Loop
PHP Extension
CLI Only
Can out perform Go and
NodeJS*
… at some things
Exploring Async PHP (SF Live Berlin 2019)
Build cool things
Build an asyncrhronous
CMS in PHP
@dantleech
Talk to me about Phpbench and Phpactor
Works for in Berlin
Examples for this talk: https://github.com/dantleech/2019-exploring-async

More Related Content

What's hot (20)

PPT
Unix Shell Scripting Basics
Sudharsan S
 
PDF
Monitoring with Syslog and EventMachine (RailswayConf 2012)
Wooga
 
PDF
Understanding PHP memory
julien pauli
 
PDF
More than syntax
Wooga
 
PDF
Monitoring with Syslog and EventMachine
Wooga
 
PDF
Ansible
Michal Haták
 
PDF
Ansible 202
Sebastian Montini
 
PDF
JDD 2017: Nginx + Lua = OpenResty (Marcin Stożek)
PROIDEA
 
PDF
Linux Network commands
Hanan Nmr
 
PDF
Introduction to shell scripting
Corrado Santoro
 
PPT
Rush, a shell that will yield to you
guestdd9d06
 
PDF
Pursue container architecture with mincs
Yuki Nishiwaki
 
PDF
Beyond Phoenix
Gabriele Lana
 
KEY
Node.js basics
Ben Lin
 
PDF
Intro to Linux Shell Scripting
vceder
 
PDF
JDO 2019: Tips and Tricks from Docker Captain - Łukasz Lach
PROIDEA
 
PDF
EC2
Igor Kapkov
 
PPT
Unix And Shell Scripting
Jaibeer Malik
 
PDF
Quick start bash script
Simon Su
 
Unix Shell Scripting Basics
Sudharsan S
 
Monitoring with Syslog and EventMachine (RailswayConf 2012)
Wooga
 
Understanding PHP memory
julien pauli
 
More than syntax
Wooga
 
Monitoring with Syslog and EventMachine
Wooga
 
Ansible
Michal Haták
 
Ansible 202
Sebastian Montini
 
JDD 2017: Nginx + Lua = OpenResty (Marcin Stożek)
PROIDEA
 
Linux Network commands
Hanan Nmr
 
Introduction to shell scripting
Corrado Santoro
 
Rush, a shell that will yield to you
guestdd9d06
 
Pursue container architecture with mincs
Yuki Nishiwaki
 
Beyond Phoenix
Gabriele Lana
 
Node.js basics
Ben Lin
 
Intro to Linux Shell Scripting
vceder
 
JDO 2019: Tips and Tricks from Docker Captain - Łukasz Lach
PROIDEA
 
Unix And Shell Scripting
Jaibeer Malik
 
Quick start bash script
Simon Su
 

Similar to Exploring Async PHP (SF Live Berlin 2019) (20)

ODP
The promise of asynchronous php
Wim Godden
 
ODP
The promise of asynchronous PHP
Wim Godden
 
ODP
The promise of asynchronous php
Wim Godden
 
ODP
The promise of asynchronous PHP
Wim Godden
 
PDF
Dependency management with Composer
Jason Grimes
 
PDF
Meet a parallel, asynchronous PHP world
Steve Maraspin
 
PDF
When symfony met promises
Marc Morera
 
PDF
php[world] 2016 - You Don’t Need Node.js - Async Programming in PHP
Adam Englander
 
PDF
You Got Async in my PHP!
Chris Tankersley
 
PPTX
Php core. get rid of bugs and contribute
Pierre Joye
 
PDF
Zend con 2016 - Asynchronous Prorgamming in PHP
Adam Englander
 
PDF
Debugging: Rules And Tools - PHPTek 11 Version
Ian Barber
 
PDF
Debugging: Rules & Tools
Ian Barber
 
PDF
Build a bot workshop async primer - php[tek]
Adam Englander
 
PDF
"Swoole: double troubles in c", Alexandr Vronskiy
Fwdays
 
PDF
Portable PHP
weltling
 
PDF
Shifting gears with Composer
Javier López
 
PPTX
How to Supercharge your PHP Web API
Aurimas Niekis
 
PDF
Asynchronous PHP and Real-time Messaging
Steve Rhoades
 
DOC
Nginx 0.8.x + php 5.2.13 (fast cgi) setup web server
wruben
 
The promise of asynchronous php
Wim Godden
 
The promise of asynchronous PHP
Wim Godden
 
The promise of asynchronous php
Wim Godden
 
The promise of asynchronous PHP
Wim Godden
 
Dependency management with Composer
Jason Grimes
 
Meet a parallel, asynchronous PHP world
Steve Maraspin
 
When symfony met promises
Marc Morera
 
php[world] 2016 - You Don’t Need Node.js - Async Programming in PHP
Adam Englander
 
You Got Async in my PHP!
Chris Tankersley
 
Php core. get rid of bugs and contribute
Pierre Joye
 
Zend con 2016 - Asynchronous Prorgamming in PHP
Adam Englander
 
Debugging: Rules And Tools - PHPTek 11 Version
Ian Barber
 
Debugging: Rules & Tools
Ian Barber
 
Build a bot workshop async primer - php[tek]
Adam Englander
 
"Swoole: double troubles in c", Alexandr Vronskiy
Fwdays
 
Portable PHP
weltling
 
Shifting gears with Composer
Javier López
 
How to Supercharge your PHP Web API
Aurimas Niekis
 
Asynchronous PHP and Real-time Messaging
Steve Rhoades
 
Nginx 0.8.x + php 5.2.13 (fast cgi) setup web server
wruben
 
Ad

More from dantleech (7)

ODP
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
dantleech
 
ODP
Incredible Machine with Pipelines and Generators
dantleech
 
ODP
Phpactor and VIM
dantleech
 
ODP
A Tale of Three Components
dantleech
 
PDF
Boltc CMS - a really quick overview
dantleech
 
PDF
Tmux quick intro
dantleech
 
PDF
Benchmarking and PHPBench
dantleech
 
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
dantleech
 
Incredible Machine with Pipelines and Generators
dantleech
 
Phpactor and VIM
dantleech
 
A Tale of Three Components
dantleech
 
Boltc CMS - a really quick overview
dantleech
 
Tmux quick intro
dantleech
 
Benchmarking and PHPBench
dantleech
 
Ad

Recently uploaded (20)

PDF
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PDF
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
PDF
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
PDF
NASA A Researcher’s Guide to International Space Station : Physical Sciences ...
Dr. PANKAJ DHUSSA
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PDF
Peak of Data & AI Encore AI-Enhanced Workflows for the Real World
Safe Software
 
PDF
Kit-Works Team Study_20250627_한달만에만든사내서비스키링(양다윗).pdf
Wonjun Hwang
 
PPTX
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
DOCX
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PPTX
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
PDF
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 
PDF
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
PPTX
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
PDF
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
PPTX
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
PPTX
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
NASA A Researcher’s Guide to International Space Station : Physical Sciences ...
Dr. PANKAJ DHUSSA
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
Peak of Data & AI Encore AI-Enhanced Workflows for the Real World
Safe Software
 
Kit-Works Team Study_20250627_한달만에만든사내서비스키링(양다윗).pdf
Wonjun Hwang
 
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Agentforce World Tour Toronto '25 - MCP with MuleSoft
Alexandra N. Martinez
 
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 
CIFDAQ Market Wrap for the week of 4th July 2025
CIFDAQ
 
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 

Exploring Async PHP (SF Live Berlin 2019)