SlideShare a Scribd company logo
The promise of asynchronous PHP
Wim Godden
Cu.be Solutions
@wimgtr
Who am I ?
Wim Godden (@wimgtr)
Where I'm from
Where I'm from
Where I'm from
Where I'm from
Where I'm from
Where I'm from
My town
My town
Belgium – the traffic
Who am I ?
Wim Godden (@wimgtr)
Founder of Cu.be Solutions (http://cu.be)
Open Source developer since 1997
Developer of PHPCompatibility, OpenX, PHPConsistent, ...
Speaker at Open Source conferences
Who are you ?
Developers ?
Ever worked with asynchronous PHP libraries ?
Node.JS ?
Synchronous processing
Insert
order
Check
payment
Update
stock
Fedex
API
Send
mail
Thank
you
page
Asynchronous processing
Insert
order
Check
payment
Update
stock
Fedex
API
Send
mail
Thank
you
page
Blocking I/O
Disk reading/writing
Network reading/writing
Communication with DB (with some exceptions)
Sending mail
...
Non-blocking = good
Work on multiple things at same time
Not entirely sequential anymore
How do you know something is finished ?
→ Events !
Events
Start
Progress update
End (successfully)
Failed
Callback hell
$one->do(function ($two) {
$two->do(function ($three) {
$three->do(function ($stillcounting) {
$stillcounting->get(function() {
throw new IQuitException();
});
});
});
});
State of asynchronous PHP
Several built-in functions
Several libraries (using the built-in functions)
Facebook Hack
Pthreads
PECL extension
Multithreading
Requires zts (thread-safe)
Pthreads
class WebRequest extends Thread {
public $url;
public $response;
public function __construct($url){
$this->url = $url;
}
public function run() {
$this->response = file_get_contents($this->url);
}
}
$request = new WebRequest("https://cu.be");
if ($request->start()) {
/* do some work here */
$a = array_fill(0, 10000000, 'test');
for ($i = 0; $i < count($a); $i++) {}
/* ensure we have data */
$request->join();
echo $request->response;
}
pcntl_fork
Forks PHP process
Multiprocessing, not multithreading
No communication between processes
No Apache
popen
child.php
<?php
/* Do some work */
echo 'Output here';
main.php
<?php
// open child process
$child = popen('php child.php', 'r');
/*
* Do some work, while already doing other
* work in the child process.
*/
// get response from child (if any) as soon at it's ready:
$response = stream_get_contents($child);
W
arning
: doesn't behave
sam
e
on
all operating
system
s
!
Sequential curl requests
$urls = ['http://www.google.com/', 'http://www.yahoo.com/', 'http://cu.be', 'http://www.microsoft.com/'];
$results = [];
foreach ($urls as $key => $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$results[$url] = curl_exec($ch);
curl_close($ch);
}
Asynchronous curl_multi requests
$urls = ['http://www.google.com/', 'http://www.yahoo.com/', 'http://cu.be','http://www.microsoft.com/'];
$chandles = [];
$mh = curl_multi_init();
foreach ($urls as $key => $url) {
$chandles[$key] = curl_init();
curl_setopt($chandles[$key], CURLOPT_URL, $url);
curl_setopt($chandles[$key], CURLOPT_HEADER, 0);
curl_setopt($chandles[$key], CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle($mh, $chandles[$key]);
}
$active = null;
do {
$mrc = curl_multi_exec($mh, $active);
} while ($active > 0);
foreach ($chandles as $ch) {
$results[curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)] = curl_multi_getcontent($ch);
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
Using Curl as async system
$c = curl_init();
curl_setopt($c, CURLOPT_URL, 'http://somewhere/sub1.php?
action=go&from=4&to=40000');
curl_setopt($c, CURLOPT_FOLLOW_LOCATION, true);
curl_setopt($c, CURLOPT_FRESH_CONNECT, true);
curl_setopt($c, CURLOPT_TIMEOUT_MS, 1);
curl_exec($c);
curl_close($c);
// Code continues after 1ms timeout
main.php
400ms
main.php
100ms
sub1.php
100ms
sub2.php
100ms
sub3.php
100ms
function1()
100ms
function2()
100ms
function3()
100ms
Libevent, libev, libuv
Event handling libraries
PHP extensions (most through PECL)
libevent = also used by Memcached
libev = not available on Windows
ReactPHP
Event-driven non-blocking I/O library
Written in PHP
Provides event-driven interface
Implements event loop
ReactPHP Event Loop
Based on ticks → 1 tick = 1 loop iteration
Timers
One-time timer
Periodic timer
Input/output → callback
ReactPHP – a simple webserver
$loop = new ReactEventLoopFactory::create();
$socket = new ReactSocketServer($loop);
$socket->listen(80);
$http = new ReactHttpServer($socket, $loop);
$http->on('request', function ($request, $response) {
$response->writeHead(200);
$response->send("Hello world!n");
});
$loop->run();
ReactPHP - structure
Event Loop
Stream
Socket
HTTP
→ stream_select (built-in)
libevent (PECL)
libev (PECL)
event (PECL)
ReactPHP - structure
Event Loop
Stream
Socket
HTTPClient DNSWHOIS HTTPClient
WebsocketSOCKS IRC
Timers – one-time
$ourTimer = $loop->addTimer(
15,
function() {
throw new Exception('We have a timeout somewhere');
}
);
$loop->cancelTimer($ourTimer);
Timers - periodic
$aliveTimer = $loop->addPeriodicTimer(
30,
function() use ($host) {
if (isHostAlive($host) === false) {
$loop->cancelTimer($aliveTimer);
throw new Exception('Host ' . $host . ' is dead', HOST_IS_DEAD);
}
}
);
ReactPHP – Promises
$deferred = new SomeclassExtendingPromiseDeferred();
$promise = $deferred->promise()
->then(
function ($value) {
// Resolved, use $value
},
function ($reason) {
// Rejected, show or log $reason
},
function ($status) {
// Progress changed, show or log $status
}
);
ReactPHP – Chaining then() statements
$promise = $deferred->promise()
->then(
function ($a) {
return $a * 2;
}
)
->then(
function ($b) {
return $b * 2;
}
)
->then(
function ($c) {
echo 'c is now ' . $c;
}
);
$deferred->resolve(1); // Will output 'c is now 4'
ReactPHP – Chaining then() statements
$promise = $deferred->promise()
->then(
function ($a) {
if ($a > 5) {
return $a * 2;
} else {
throw new Exception('Too small');
}
}
)
->then(
function ($a) {
echo $a;
},
function ($e) {
echo "We got this exception : " . $e->getMessage();
}
);
$deferred->resolve(10); // Will output 20
$deferred->resolve(1); // Will output : We got this exception : Too small
ReactPHP – Promises example
Hostname lookup – the old way
$hostnames = explode(',', $_POST['hostnames']);
$hostnames = FilterDangerousHostnames($hostnames);
$success = array();
foreach ($hostnames as $hostname) {
$ip = gethostbyname($hostname);
if ($ip != $hostname) {
$success[] = “$hostname ($ip)”;
}
}
echo 'Success resolving ' . implode(', ', $success);
Sequential
→ 10 hostnames → 10 sequential lookups
DNS timeouts → delays
Hostname lookup – the async way
$loop = ReactEventLoopFactory::create();
$factory = new ReactDnsResolverFactory();
$dns = $factory->create('8.8.8.8', $loop);
$hostnames = explode(',', $_POST['hostnames']);
$hostnames = FilterDangerousHostnames($hostnames);
$promises = array();
foreach ($hostnames as $hostname) {
$promises[] = $dns->resolve($hostname)
->then(
function($ip) use ($hostname) {
return "$hostname ($ip)";
},
function($error) { return ''; }
);
}
ReactPromiseall($promises)->then(
function($hostnames) {
$hostnames = array_filter($hostnames, 'strlen');
echo 'Success in resolving ' . implode(', ', $hostnames) . "n";
}
);
$loop->run();
ReactPHP – Promises vs Streams
Promises
→ Very useful
→ But : limited to simple return values
Streams
→ Much more powerful
→ Also somewhat more complex
ReactPHP - Streams
Either :
Readable
Writable
Both
Example :
Through stream = filter
Limited only by your imagination !
$loop = ReactEventLoopFactory::create();
$source = new ReactStreamStream(fopen('source.txt', 'r'), $loop);
$filter = new MyLibStreamAlnumFilter();
$dest = new ReactStreamStream(fopen('dest.txt', 'w'), $loop);
$source->pipe($filter)->pipe($dest);
$loop->run();
$loop = ReactEventLoopFactory::create();
$socket = new ReactSocketServer($loop);
$clients = new SplObjectStorage();
$i = 0;
$socket->on('connection', function($connection) use($clients, &$i) {
$connection->id = ++$i;
$connection->write('Enter your nickname: ');
$connection->on('data', function($message) use($clients, $connection) {
if (empty($connection->nickName)) {
$connection->nickName = $message;
} else {
foreach ($clients as $client) {
if ($client->id == $connection->id) {
continue;
}
$client->write(
sprintf(
'<%s> %s',
$connection->nickName,
$message
)
);
}
}
});
$clients->attach($connection);
});
$socket->listen(1337);
$loop->run();
PubSub using ZeroMQ
$context = new ReactZMQContext($loop);
$pub = $context->getSocket(ZMQ::SOCKET_PUB);
$pub->connect('tcp://127.0.0.1:5555');
$i = 0;
$loop->addPeriodicTimer(1, function () use (&$i, $pub) {
$i++;
$pub->sendmulti(array('phpaustralia', 'Message ' .$i));
});
PubSub using ZeroMQ
$context = new ReactZMQContext($loop);
$sub = $context->getSocket(ZMQ::SOCKET_SUB);
$sub->bind('tcp://127.0.0.1:5555');
$sub->subscribe('phpaustralia');
$sub->on('message', function ($msg) {
echo "Received: $msgn";
});
Based on ReactPHP
Some golden rules & warnings
Golden rule #1 : asynchronous != faster code
Golden rule #2 : don't assume your code will remain as fast
Golden rule #3 : if you don't need a response, don't wait for one
Warning : async does not guarantee execution order !
Questions ?
Questions ?
Thanks !
@wimgtr
wim@cu.be
Please provide some feedback : https://joind.in/talk/9c6da
Ad

More Related Content

What's hot (20)

My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
When dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniquesWhen dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniques
Wim Godden
 
Asynchronous I/O in PHP
Asynchronous I/O in PHPAsynchronous I/O in PHP
Asynchronous I/O in PHP
Thomas Weinert
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
Flavio Poletti
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
Flavio Poletti
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
XSolve
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
Domenic Denicola
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
Mark Baker
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
Fabien Potencier
 
Beyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeBeyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the code
Wim Godden
 
Fatc
FatcFatc
Fatc
Wade Arnold
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
Hugo Hamon
 
The state of your own hypertext preprocessor
The state of your own hypertext preprocessorThe state of your own hypertext preprocessor
The state of your own hypertext preprocessor
Alessandro Nadalin
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Masahiro Nagano
 
Python and EM CLI: The Enterprise Management Super Tools
Python and EM CLI: The Enterprise Management Super ToolsPython and EM CLI: The Enterprise Management Super Tools
Python and EM CLI: The Enterprise Management Super Tools
Seth Miller
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
G Woo
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
Bill Chang
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
Kirill Chebunin
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
When dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniquesWhen dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniques
Wim Godden
 
Asynchronous I/O in PHP
Asynchronous I/O in PHPAsynchronous I/O in PHP
Asynchronous I/O in PHP
Thomas Weinert
 
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
XSolve
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
Mark Baker
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
Fabien Potencier
 
Beyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeBeyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the code
Wim Godden
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
Hugo Hamon
 
The state of your own hypertext preprocessor
The state of your own hypertext preprocessorThe state of your own hypertext preprocessor
The state of your own hypertext preprocessor
Alessandro Nadalin
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Masahiro Nagano
 
Python and EM CLI: The Enterprise Management Super Tools
Python and EM CLI: The Enterprise Management Super ToolsPython and EM CLI: The Enterprise Management Super Tools
Python and EM CLI: The Enterprise Management Super Tools
Seth Miller
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
G Woo
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
Bill Chang
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
Kirill Chebunin
 

Viewers also liked (6)

Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?
Wim Godden
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
Wim Godden
 
Distributed Applications with Perl & Gearman
Distributed Applications with Perl & GearmanDistributed Applications with Perl & Gearman
Distributed Applications with Perl & Gearman
Issac Goldstand
 
ZeroMQ: Super Sockets - by J2 Labs
ZeroMQ: Super Sockets - by J2 LabsZeroMQ: Super Sockets - by J2 Labs
ZeroMQ: Super Sockets - by J2 Labs
James Dennis
 
Asynchronous PHP. Myth? Reality!
Asynchronous PHP. Myth? Reality!Asynchronous PHP. Myth? Reality!
Asynchronous PHP. Myth? Reality!
Alexander Lisachenko
 
Consuming RESTful services in PHP
Consuming RESTful services in PHPConsuming RESTful services in PHP
Consuming RESTful services in PHP
Zoran Jeremic
 
Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?
Wim Godden
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
Wim Godden
 
Distributed Applications with Perl & Gearman
Distributed Applications with Perl & GearmanDistributed Applications with Perl & Gearman
Distributed Applications with Perl & Gearman
Issac Goldstand
 
ZeroMQ: Super Sockets - by J2 Labs
ZeroMQ: Super Sockets - by J2 LabsZeroMQ: Super Sockets - by J2 Labs
ZeroMQ: Super Sockets - by J2 Labs
James Dennis
 
Consuming RESTful services in PHP
Consuming RESTful services in PHPConsuming RESTful services in PHP
Consuming RESTful services in PHP
Zoran Jeremic
 
Ad

Similar to The promise of asynchronous php (20)

The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
Wim Godden
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
Kacper Gunia
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Kacper Gunia
 
Generating Power with Yield
Generating Power with YieldGenerating Power with Yield
Generating Power with Yield
Jason Myers
 
Mojo as a_client
Mojo as a_clientMojo as a_client
Mojo as a_client
Marcus Ramberg
 
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Péhápkaři
 
Swoole Overview
Swoole OverviewSwoole Overview
Swoole Overview
Manuel Baldassarri
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middleware
Kuan Yen Heng
 
Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12
Jakub Zalas
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time Messaging
Steve Rhoades
 
Micropage in microtime using microframework
Micropage in microtime using microframeworkMicropage in microtime using microframework
Micropage in microtime using microframework
Radek Benkel
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
Workhorse Computing
 
ReactPHP
ReactPHPReactPHP
ReactPHP
Philip Norton
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Tatsuhiko Miyagawa
 
Tatsumaki
TatsumakiTatsumaki
Tatsumaki
Tatsuhiko Miyagawa
 
When symfony met promises
When symfony met promises When symfony met promises
When symfony met promises
Marc Morera
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
Kang-min Liu
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP Extension
Adam Trachtenberg
 
Web 8 | Introduction to PHP
Web 8 | Introduction to PHPWeb 8 | Introduction to PHP
Web 8 | Introduction to PHP
Mohammad Imam Hossain
 
Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?
Lucas Witold Adamus
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
Wim Godden
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
Kacper Gunia
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Kacper Gunia
 
Generating Power with Yield
Generating Power with YieldGenerating Power with Yield
Generating Power with Yield
Jason Myers
 
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Péhápkaři
 
Durian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middlewareDurian: a PHP 5.5 microframework with generator-style middleware
Durian: a PHP 5.5 microframework with generator-style middleware
Kuan Yen Heng
 
Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12
Jakub Zalas
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time Messaging
Steve Rhoades
 
Micropage in microtime using microframework
Micropage in microtime using microframeworkMicropage in microtime using microframework
Micropage in microtime using microframework
Radek Benkel
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
Workhorse Computing
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Tatsuhiko Miyagawa
 
When symfony met promises
When symfony met promises When symfony met promises
When symfony met promises
Marc Morera
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
Kang-min Liu
 
Dirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP ExtensionDirty Secrets of the PHP SOAP Extension
Dirty Secrets of the PHP SOAP Extension
Adam Trachtenberg
 
Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?
Lucas Witold Adamus
 
Ad

More from Wim Godden (19)

Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
Wim Godden
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to life
Wim Godden
 
The why and how of moving to php 8
The why and how of moving to php 8The why and how of moving to php 8
The why and how of moving to php 8
Wim Godden
 
The why and how of moving to php 7
The why and how of moving to php 7The why and how of moving to php 7
The why and how of moving to php 7
Wim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
Wim Godden
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to life
Wim Godden
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developers
Wim Godden
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
Wim Godden
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
Wim Godden
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
Wim Godden
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
Wim Godden
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developers
Wim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
Practical git for developers
Practical git for developersPractical git for developers
Practical git for developers
Wim Godden
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
Wim Godden
 
When dynamic becomes static
When dynamic becomes staticWhen dynamic becomes static
When dynamic becomes static
Wim Godden
 
When dynamic becomes static
When dynamic becomes staticWhen dynamic becomes static
When dynamic becomes static
Wim Godden
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
Wim Godden
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to life
Wim Godden
 
The why and how of moving to php 8
The why and how of moving to php 8The why and how of moving to php 8
The why and how of moving to php 8
Wim Godden
 
The why and how of moving to php 7
The why and how of moving to php 7The why and how of moving to php 7
The why and how of moving to php 7
Wim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
Wim Godden
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to life
Wim Godden
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developers
Wim Godden
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
Wim Godden
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
Wim Godden
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
Wim Godden
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
Wim Godden
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developers
Wim Godden
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
Wim Godden
 
Practical git for developers
Practical git for developersPractical git for developers
Practical git for developers
Wim Godden
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
Wim Godden
 
When dynamic becomes static
When dynamic becomes staticWhen dynamic becomes static
When dynamic becomes static
Wim Godden
 
When dynamic becomes static
When dynamic becomes staticWhen dynamic becomes static
When dynamic becomes static
Wim Godden
 

Recently uploaded (20)

DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
TrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business ConsultingTrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business Consulting
Trs Labs
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Massive Power Outage Hits Spain, Portugal, and France: Causes, Impact, and On...
Aqusag Technologies
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
TrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business ConsultingTrsLabs - Fintech Product & Business Consulting
TrsLabs - Fintech Product & Business Consulting
Trs Labs
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 

The promise of asynchronous php

  • 1. The promise of asynchronous PHP Wim Godden Cu.be Solutions @wimgtr
  • 2. Who am I ? Wim Godden (@wimgtr)
  • 11. Belgium – the traffic
  • 12. Who am I ? Wim Godden (@wimgtr) Founder of Cu.be Solutions (http://cu.be) Open Source developer since 1997 Developer of PHPCompatibility, OpenX, PHPConsistent, ... Speaker at Open Source conferences
  • 13. Who are you ? Developers ? Ever worked with asynchronous PHP libraries ? Node.JS ?
  • 16. Blocking I/O Disk reading/writing Network reading/writing Communication with DB (with some exceptions) Sending mail ...
  • 17. Non-blocking = good Work on multiple things at same time Not entirely sequential anymore How do you know something is finished ? → Events !
  • 19. Callback hell $one->do(function ($two) { $two->do(function ($three) { $three->do(function ($stillcounting) { $stillcounting->get(function() { throw new IQuitException(); }); }); }); });
  • 20. State of asynchronous PHP Several built-in functions Several libraries (using the built-in functions) Facebook Hack
  • 22. Pthreads class WebRequest extends Thread { public $url; public $response; public function __construct($url){ $this->url = $url; } public function run() { $this->response = file_get_contents($this->url); } } $request = new WebRequest("https://cu.be"); if ($request->start()) { /* do some work here */ $a = array_fill(0, 10000000, 'test'); for ($i = 0; $i < count($a); $i++) {} /* ensure we have data */ $request->join(); echo $request->response; }
  • 23. pcntl_fork Forks PHP process Multiprocessing, not multithreading No communication between processes No Apache
  • 24. popen child.php <?php /* Do some work */ echo 'Output here'; main.php <?php // open child process $child = popen('php child.php', 'r'); /* * Do some work, while already doing other * work in the child process. */ // get response from child (if any) as soon at it's ready: $response = stream_get_contents($child); W arning : doesn't behave sam e on all operating system s !
  • 25. Sequential curl requests $urls = ['http://www.google.com/', 'http://www.yahoo.com/', 'http://cu.be', 'http://www.microsoft.com/']; $results = []; foreach ($urls as $key => $url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $results[$url] = curl_exec($ch); curl_close($ch); }
  • 26. Asynchronous curl_multi requests $urls = ['http://www.google.com/', 'http://www.yahoo.com/', 'http://cu.be','http://www.microsoft.com/']; $chandles = []; $mh = curl_multi_init(); foreach ($urls as $key => $url) { $chandles[$key] = curl_init(); curl_setopt($chandles[$key], CURLOPT_URL, $url); curl_setopt($chandles[$key], CURLOPT_HEADER, 0); curl_setopt($chandles[$key], CURLOPT_RETURNTRANSFER, 1); curl_multi_add_handle($mh, $chandles[$key]); } $active = null; do { $mrc = curl_multi_exec($mh, $active); } while ($active > 0); foreach ($chandles as $ch) { $results[curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)] = curl_multi_getcontent($ch); curl_multi_remove_handle($mh, $ch); } curl_multi_close($mh);
  • 27. Using Curl as async system $c = curl_init(); curl_setopt($c, CURLOPT_URL, 'http://somewhere/sub1.php? action=go&from=4&to=40000'); curl_setopt($c, CURLOPT_FOLLOW_LOCATION, true); curl_setopt($c, CURLOPT_FRESH_CONNECT, true); curl_setopt($c, CURLOPT_TIMEOUT_MS, 1); curl_exec($c); curl_close($c); // Code continues after 1ms timeout main.php 400ms main.php 100ms sub1.php 100ms sub2.php 100ms sub3.php 100ms function1() 100ms function2() 100ms function3() 100ms
  • 28. Libevent, libev, libuv Event handling libraries PHP extensions (most through PECL) libevent = also used by Memcached libev = not available on Windows
  • 29. ReactPHP Event-driven non-blocking I/O library Written in PHP Provides event-driven interface Implements event loop
  • 30. ReactPHP Event Loop Based on ticks → 1 tick = 1 loop iteration Timers One-time timer Periodic timer Input/output → callback
  • 31. ReactPHP – a simple webserver $loop = new ReactEventLoopFactory::create(); $socket = new ReactSocketServer($loop); $socket->listen(80); $http = new ReactHttpServer($socket, $loop); $http->on('request', function ($request, $response) { $response->writeHead(200); $response->send("Hello world!n"); }); $loop->run();
  • 32. ReactPHP - structure Event Loop Stream Socket HTTP → stream_select (built-in) libevent (PECL) libev (PECL) event (PECL)
  • 33. ReactPHP - structure Event Loop Stream Socket HTTPClient DNSWHOIS HTTPClient WebsocketSOCKS IRC
  • 34. Timers – one-time $ourTimer = $loop->addTimer( 15, function() { throw new Exception('We have a timeout somewhere'); } ); $loop->cancelTimer($ourTimer);
  • 35. Timers - periodic $aliveTimer = $loop->addPeriodicTimer( 30, function() use ($host) { if (isHostAlive($host) === false) { $loop->cancelTimer($aliveTimer); throw new Exception('Host ' . $host . ' is dead', HOST_IS_DEAD); } } );
  • 36. ReactPHP – Promises $deferred = new SomeclassExtendingPromiseDeferred(); $promise = $deferred->promise() ->then( function ($value) { // Resolved, use $value }, function ($reason) { // Rejected, show or log $reason }, function ($status) { // Progress changed, show or log $status } );
  • 37. ReactPHP – Chaining then() statements $promise = $deferred->promise() ->then( function ($a) { return $a * 2; } ) ->then( function ($b) { return $b * 2; } ) ->then( function ($c) { echo 'c is now ' . $c; } ); $deferred->resolve(1); // Will output 'c is now 4'
  • 38. ReactPHP – Chaining then() statements $promise = $deferred->promise() ->then( function ($a) { if ($a > 5) { return $a * 2; } else { throw new Exception('Too small'); } } ) ->then( function ($a) { echo $a; }, function ($e) { echo "We got this exception : " . $e->getMessage(); } ); $deferred->resolve(10); // Will output 20 $deferred->resolve(1); // Will output : We got this exception : Too small
  • 40. Hostname lookup – the old way $hostnames = explode(',', $_POST['hostnames']); $hostnames = FilterDangerousHostnames($hostnames); $success = array(); foreach ($hostnames as $hostname) { $ip = gethostbyname($hostname); if ($ip != $hostname) { $success[] = “$hostname ($ip)”; } } echo 'Success resolving ' . implode(', ', $success); Sequential → 10 hostnames → 10 sequential lookups DNS timeouts → delays
  • 41. Hostname lookup – the async way $loop = ReactEventLoopFactory::create(); $factory = new ReactDnsResolverFactory(); $dns = $factory->create('8.8.8.8', $loop); $hostnames = explode(',', $_POST['hostnames']); $hostnames = FilterDangerousHostnames($hostnames); $promises = array(); foreach ($hostnames as $hostname) { $promises[] = $dns->resolve($hostname) ->then( function($ip) use ($hostname) { return "$hostname ($ip)"; }, function($error) { return ''; } ); } ReactPromiseall($promises)->then( function($hostnames) { $hostnames = array_filter($hostnames, 'strlen'); echo 'Success in resolving ' . implode(', ', $hostnames) . "n"; } ); $loop->run();
  • 42. ReactPHP – Promises vs Streams Promises → Very useful → But : limited to simple return values Streams → Much more powerful → Also somewhat more complex
  • 43. ReactPHP - Streams Either : Readable Writable Both Example : Through stream = filter Limited only by your imagination ! $loop = ReactEventLoopFactory::create(); $source = new ReactStreamStream(fopen('source.txt', 'r'), $loop); $filter = new MyLibStreamAlnumFilter(); $dest = new ReactStreamStream(fopen('dest.txt', 'w'), $loop); $source->pipe($filter)->pipe($dest); $loop->run();
  • 44. $loop = ReactEventLoopFactory::create(); $socket = new ReactSocketServer($loop); $clients = new SplObjectStorage(); $i = 0; $socket->on('connection', function($connection) use($clients, &$i) { $connection->id = ++$i; $connection->write('Enter your nickname: '); $connection->on('data', function($message) use($clients, $connection) { if (empty($connection->nickName)) { $connection->nickName = $message; } else { foreach ($clients as $client) { if ($client->id == $connection->id) { continue; } $client->write( sprintf( '<%s> %s', $connection->nickName, $message ) ); } } }); $clients->attach($connection); }); $socket->listen(1337); $loop->run();
  • 45. PubSub using ZeroMQ $context = new ReactZMQContext($loop); $pub = $context->getSocket(ZMQ::SOCKET_PUB); $pub->connect('tcp://127.0.0.1:5555'); $i = 0; $loop->addPeriodicTimer(1, function () use (&$i, $pub) { $i++; $pub->sendmulti(array('phpaustralia', 'Message ' .$i)); });
  • 46. PubSub using ZeroMQ $context = new ReactZMQContext($loop); $sub = $context->getSocket(ZMQ::SOCKET_SUB); $sub->bind('tcp://127.0.0.1:5555'); $sub->subscribe('phpaustralia'); $sub->on('message', function ($msg) { echo "Received: $msgn"; });
  • 48. Some golden rules & warnings Golden rule #1 : asynchronous != faster code Golden rule #2 : don't assume your code will remain as fast Golden rule #3 : if you don't need a response, don't wait for one Warning : async does not guarantee execution order !
  • 51. Thanks ! @wimgtr [email protected] Please provide some feedback : https://joind.in/talk/9c6da