SlideShare a Scribd company logo
When Symfony
met Promises
Hello!
I am Marc Morera
Owner of Apisearch and
php.coach
You can find me at:
@mmoreram
2
Summary
◎ Regular PHP applications
◎ PHP-PM
◎ ReactPHP principles
◎ ReactPHP server
◎ Reactive domain
◎ ReactPHP Symfony Kernel
◎ ReactPHP Symfony Server
3
1.
Regular PHP
applications
… until now
4
Let’s split our applications in 3 zones
FrameworkServer Domain + I/O
5
Server
HTTP
Server
New
Kernel
handle(req)
6
Server
An HTTP server take one
HTTP request, we instance
a new Kernel, and handle
a transformed PSR
request. We return an
HTTP Response
7
Server
An HTTP server take one
HTTP request, we
instance a new Kernel,
and handle a transformed
PSR request. We return an
HTTP Response
8
$kernel = new Kernel($env, $debug);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
9
Framework
Routing
Controller
View (?)
10
Framework
The framework decides
what controller should be
executed given a route,
and what view should
render, given a controller.
11
$controller = $event->getController();
$arguments = $event->getArguments();
// call controller
$response = $controller(...$arguments);
12
Domain + I/O
Controller/
domain/
Redis/
13
Domain + I/O
We have our domain,
where all happens. Our
classes, our chosen
libraries and our business
logic. We can place I/O like
Redis calls in this group
14
$element = $repository->find('123');
$element->changeSomething();
$repository->save($element);
// I'm done
15
PHP
Is a slow, A very slow, an
extremely slow language.
16
PHP slowness reasons
◎ ORMs hydration
◎ ORMs lazy loading
◎ ORMs themselves
◎ ORMs ...
17
PHP slowness reasons
◎ ORMs hydration
◎ ORMs lazy loading
◎ ORMs themselves
◎ ORMs …
◎ Kernel recreation
18
“
Rebuilding the Kernel means
rebuilding all used services,
including clients
19
~10ms
Nginx 1.10 + PHP7.3-FPM
// 100 reqs / sec / thread
20
A/B benchmark - c(50), n(1000)
Nginx PHP-PM ReactPHP
50% 53ms - -
75% 58ms - -
95% 63ms - -
21
A/B benchmark - c(100), n(5000)
Nginx PHP-PM ReactPHP
50% 98ms - -
75% 111ms - -
95% 182ms - -
22
2.
PHP-PM
… as a natural step
23
PHP-PM
PHP-PM is a process
manager, supercharger
and load balancer for PHP
applications.
(Github repository description)
24
PHP-PM
PHP-PM
N
ReactPHP
threads
(N cores)
APP
25
require {
“php-pm/php-pm”: “*”,
“php-pm/httpkernel-adapter”: “*”
}
26
vendor/bin/ppm start 
--host=0.0.0.0 
--port=80 
--bootstrap=symfony 
--app-env=prod 
--debug=0 
--workers 20
27
A/B benchmark - c(50), n(1000)
Nginx PHP-PM ReactPHP
50% 53ms 27ms -
75% 58ms 31ms -
95% 63ms 55ms -
28
Goods
- Already works with N
ReactPHP servers
- This N is variable
- Static content
- Easy to install and configure
- Adapter for Symfony kernel
built-in
- No need of Nginx
PHP-PM
Bads ?
29
Goods
- Already works only with N
ReactPHP servers
- This N is variable
- Static content
- Easy to install and configure
- Adapter for Symfony kernel
built-in
- No need of Nginx
PHP-PM
Bads
- Each ReactPHP server act as
a regular sync server. One
request after the last
- 10 servers + 10 long time
requests = fail
- Code too complex to work
with
30
3.
ReactPHP principles
… as a change of paradigm
31
32
Async
Your code that includes,
somewhere, a result of an
I/O operation, will return
something. Eventually.
33
// t=0
$result = $redis->get(‘something’);
// t=1
34
// t=0
$promise = $redis
->get(‘something’)
->then(function($result) {
// t=1
});
// t=0
35
// t=0
$promise = $redis
->get(‘something’)
->then(function($result) use ($client) {
// t=1
return $client->hget(“hash”, $result);
})
->then(function($hashResult) {
// t=2
});
// t=0
36
Non
Blocking
An event loop treats all your
Promises in a non-blocking
way.
37
// t=0
$promise = $httpClient
->get(“http://slowpage.es”)
->then(function($result) use ($client) {
// t=10
// Do whatever
});
// t=0
38
// t=0
$promise = $redis
->get(‘something’)
->then(function($result) use ($client) {
// t=1
// Do whatever
});
->then(function($result) use ($client) {
// t=6
// Do whatever
});
// t=0
// t=0
$promise = $httpClient
->get(“http://slowpage.es”)
->then(function($result) use ($client) {
// t=10 (Third resolved)
// Do whatever
});
// t=0
39
// t=0
$promise = $redis
->get(‘something’)
->then(function($result) use ($client) {
// t=1 (First resolved)
// Do whatever
});
->then(function($result) use ($client) {
// t=6 (Second resolved)
// Do whatever
});
// t=0
Promise
A class that can be fulfilled
(value?) or rejected
(Exception)
40
$promise = $redis
->get(‘somevalue’)
->then(function($value) {
// Everything OK
}, function(Exception $e) {
// Exception was thrown
});
41
Promise
A promise is fulfilled when it
returns nothing, a simple
value or another Fulfilled
promise
42
$promise = $redis
->get(‘somevalue’)
->then(function($value) {
// Everything OK
return ‘OK’;
});
43
$promise = $redis
->get(‘somevalue’)
->then(function($value) use ($redis) {
// Everything OK
return $redis->hgetall(‘hash’);
});
44
Promise
You can concat Promises in
order to make your code
pretty easy to read
45
$promise = $redis
->get(‘somevalue’)
->then(function($value) use ($redis) {
// Everything OK
return $redis->hgetall(‘hash’);
})
->then(function($hashList) {
return count($hashList);
});
46
Event Loop
The loop can manage as
many promises as you can,
even generated from other
libraries (Redis, Mysql...)
47
// Ridiculous simplification of a Loop
while (queue.waitForMessage()) {
queue.processNextMessage();
}
48
ReactPHP libraries
Some of them are part of the core of the application
◎ /http - HTTPS server for ReactPHP
◎ /promises - Promises implementation
◎ /event-loop - EventLoop implementation
◎ /stream - PHP Streams wrapper for ReactPHP
◎ /socket - Socket server and connections for ReactPHP
49
ReactPHP libraries
And some of them just side libraries to use on top of it
◎ Redis client
◎ Mysql client
◎ AMQP client
◎ Filesystem
◎ HTTP Client
◎ DNS Resolver
◎ Cache
50
4.
ReactPHP server
… as a reduction of the solution
51
PHP-PM
PHP-PM
N
ReactPHP
threads
(N cores)
APP
52
PHP-PM
1 ReactPHP
thread
APP
53
$kernel = new Kernel();
$http = new Server(function (ServerRequestInterface $httpRequest) use ($kernel) {
return new Promise(function ($resolve, $reject) use ($httpRequest, $kernel) {
$symfonyRequest = $this->toSymfonyRequest($httpRequest);
$symfonyResponse = $kernel->handle($symfonyRequest);
$httpResponse = $this->toHttpResponse($symfonyResponse);
$resolve($httpResponse);
});
});
$http->listen($socket);
$loop->run();
54
$kernel = new Kernel();
$http = new Server(function (ServerRequestInterface $httpRequest) use ($kernel) {
return new Promise(function ($resolve, $reject) use ($httpRequest, $kernel) {
$symfonyRequest = $this->toSymfonyRequest($httpRequest);
$symfonyResponse = $kernel->handle($symfonyRequest);
$httpResponse = $this->toHttpResponse($symfonyResponse);
$resolve($httpResponse);
});
});
$http->listen($socket);
$loop->run();
55
$controller = $event->getController();
$arguments = $event->getArguments();
// call controller
$response = $controller(...$arguments);
56
$kernel = new Kernel();
$http = new Server(function (ServerRequestInterface $httpRequest) use ($kernel) {
return new Promise(function ($resolve, $reject) use ($httpRequest, $kernel) {
$symfonyRequest = $this->toSymfonyRequest($httpRequest);
// t=0
$symfonyResponse = $kernel->handle($symfonyRequest);
// t=1
$httpResponse = $this->toHttpResponse($symfonyResponse);
$resolve($httpResponse);
});
});
$http->listen($socket);
$loop->run();
57
5.
Reactive domain
… as our first BIG change
58
Some
changes
Let’ see how we can turn our
domain a little bit reactive.
This is a slow step by step
process
59
Controller Domain Repository
60
$entity = $client->find(‘123’);
$entity->disable();
$client->insert($entity);
return $entity;
return $client
->find(‘123’)
->then(function($entity) use ($client) {
$entity->disable();
return $client->insert($entity);
});
Controller Domain Repository
61
$entity = $repository->disable($entity);
$eventDispatcher->dispatch(
‘entity.disabled’,
new EntityWasDisabled($entity)
);
return;
Return $repository
->disable($entity)
->then(function($entity) use ($eventDispatcher) {
$eventDispatcher->dispatch(
‘entity.disabled’,
new EntityWasDisabled($entity)
);
});
Controller Domain Repository
62
$this
->entityDisabler
->disableEntity($entity);
return JsonResponse(“Entity disabled”);
return $this
->entityDisabler
->disableEntity($entity)
->then(function() {
return new JsonResponse(‘Entity disabled”);
});
“
Controller in Symfony must return
a Response object or an array if
you use Twig
63
Let’s split our applications in 3 zones
Framework
Sync
Server
Async
Domain + I/O
Async
64
Controller Domain Repository
65
$this
->entityDisabler
->disableEntity($entity);
return JsonResponse(“Entity disabled”);
$promise = $this
->entityDisabler
->disableEntity($entity)
->then(function() {
return new JsonResponse(‘Entity disabled”);
});
return Blockawait($promise); // Async to Sync
6.
ReactPHP Symfony
Kernel
… as the solution
66
$controller = $event->getController();
$arguments = $event->getArguments();
// call controller
$response = $controller(...$arguments);
67
$controller = $event->getController();
$arguments = $event->getArguments();
// call controller
return $controller(...$arguments)
->then(function($response) {
// Do whatever
});
Symfony
Async
Kernel
Working with an async
kernel in Symfony mean
some specific changes
68
Let’s split our applications in 3 zones
Framework
Async
Server
Async
Domain + I/O
Async
69
“
Controllers must return a Promise,
which eventually will return a
Response or an Array
70
“
Event listeners can return a
Promise as part of your domain.
Check inside and outside the
Promise effects
71
/**
* Handle get Response.
*
* @param GetResponseEvent $event
*
* @return PromiseInterface
*/
public function handleGetResponsePromiseA(GetResponseEvent $event)
{
$promise = (new FulfilledPromise())
->then(function () use ($event) {
// This line is executed eventually after the previous listener
// promise is fulfilled
$event->setResponse(new Response('A'));
});
// This line is executed before the first event listener promise is
// fulfilled
return $promise;
}
72
“
Each I/O operation must be
performed by using Reactive
libraries (filesystem, Redis, Http
requests, Mysql, RabbitMQ...)
73
“
A single sync I/O operation will
make your whole application sync
74
Symfony
Async
Kernel
https://github.com/apisearch-io/symfony-async-kernel
https://github.com/apisearch-io/symfony-react-demo
75
7.
ReactPHP Symfony
server
… as the main server
76
Let’s split our applications in 3 zones
Framework
Async
Server
Async
Domain + I/O
Async
77
Async
Server
https://github.com/apisearch-io/symfony-react-server
78
require {
"apisearch-io/symfony-async-http-kernel": "^0.1",
"apisearch-io/symfony-react-server": "^0.1"
}
79
use SymfonyComponentHttpKernelAsyncKernel;
class Kernel extends AsyncKernel
{
use MicroKernelTrait;
80
php vendor/bin/server 
0.0.0.0:80 
--dev 
--debug 
--non-blocking
81
A/B benchmark - c(1), n(1000)
Nginx PHP-PM ReactPHP
50% 8ms 1ms 1ms
75% 10ms 2ms 1ms
95% 12ms 5ms 2ms
82
A/B benchmark - c(20), n(1000)
Nginx PHP-PM ReactPHP
50% 19ms 17ms 14ms
75% 23ms 20ms 16ms
95% 34ms 23ms 18ms
83
A/B benchmark - c(50), n(1000)
Nginx PHP-PM ReactPHP
50% 85ms 37ms 22ms
75% 90ms 45ms 23ms
95% 107ms ~1s 25ms
84
A/B benchmark - c(200), n(10000)
Nginx PHP-PM ReactPHP
50% - 45ms 23ms
75% - 53ms 27ms
95% - 65ms 31ms
85
A/B benchmark - c(300), n(10000)
Nginx PHP-PM ReactPHP
50% - 40ms 24ms
75% - 68ms 25ms
95% - 80ms 31ms
86
Next steps
The future of PHP will be async, so you better be ready for
that
◎ Work for a Promises PSR. Let frameworks depend on
an interface instead of an implementation
◎ Start doing some serious stuff with Promises in PHP
◎ We should start seeing some live projects on top of
ReactPHP - Apisearch soon!
87
Next steps
◎ Some libraries should be adapted to Reactive
programming, or we should create new (DBAL, Logger,
Elasticsearch client…)
◎ Start talking a little bit more about this, because a
language is not it’s code, but how far his community
can go.
88
Thanks!
Any questions?
You can find me at:
@mmoreram &
yuhu@mmoreram.com
89

More Related Content

PDF
ESCUELA DE VERANO 2014
ODP
The promise of asynchronous php
ODP
The promise of asynchronous php
ODP
The promise of asynchronous PHP
ODP
The promise of asynchronous PHP
PPTX
ReactPHP + Symfony
PDF
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
PDF
API Platform 2.1: when Symfony meets ReactJS (Symfony Live 2017)
ESCUELA DE VERANO 2014
The promise of asynchronous php
The promise of asynchronous php
The promise of asynchronous PHP
The promise of asynchronous PHP
ReactPHP + Symfony
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
API Platform 2.1: when Symfony meets ReactJS (Symfony Live 2017)

Similar to When symfony met promises (20)

PDF
"Building Modern PHP Applications" - Jackson Murtha, South Dakota Code Camp 2012
PDF
Zend con 2016 - Asynchronous Prorgamming in PHP
PDF
PHP is the King, nodejs is the Prince and Lua is the fool
PDF
React PHP: the NodeJS challenger
PDF
php[world] 2016 - You Don’t Need Node.js - Async Programming in PHP
PDF
ReactPHP
PDF
Build powerfull and smart web applications with Symfony2
PDF
PHP Web Development.pdf
PPTX
Ran Mizrahi - Symfony2 meets Drupal8
PPTX
How to Supercharge your PHP Web API
PDF
Build a bot workshop async primer - php[tek]
PDF
Symfony2 San Francisco Meetup 2009
PDF
Silex and Twig (PHP Dorset talk)
PDF
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
PDF
Php sdk-v3-async
PDF
symfony_from_scratch
PDF
symfony_from_scratch
PPTX
Introduction to Laravel Framework (5.2)
PDF
Php and-web-services-24402
PDF
Symfony components in the wild, PHPNW12
"Building Modern PHP Applications" - Jackson Murtha, South Dakota Code Camp 2012
Zend con 2016 - Asynchronous Prorgamming in PHP
PHP is the King, nodejs is the Prince and Lua is the fool
React PHP: the NodeJS challenger
php[world] 2016 - You Don’t Need Node.js - Async Programming in PHP
ReactPHP
Build powerfull and smart web applications with Symfony2
PHP Web Development.pdf
Ran Mizrahi - Symfony2 meets Drupal8
How to Supercharge your PHP Web API
Build a bot workshop async primer - php[tek]
Symfony2 San Francisco Meetup 2009
Silex and Twig (PHP Dorset talk)
Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)
Php sdk-v3-async
symfony_from_scratch
symfony_from_scratch
Introduction to Laravel Framework (5.2)
Php and-web-services-24402
Symfony components in the wild, PHPNW12
Ad

More from Marc Morera (6)

PDF
When e-commerce meets Symfony
PDF
El Efecto "Este código es una basura"
PDF
Dependency injection
PDF
Gearman bundle, Warszawa 2013 edition
PDF
Crawling the world
PDF
Rsqueue bundle 06.2013
When e-commerce meets Symfony
El Efecto "Este código es una basura"
Dependency injection
Gearman bundle, Warszawa 2013 edition
Crawling the world
Rsqueue bundle 06.2013
Ad

Recently uploaded (20)

PDF
III.4.1.2_The_Space_Environment.p pdffdf
PPTX
CH1 Production IntroductoryConcepts.pptx
PDF
PREDICTION OF DIABETES FROM ELECTRONIC HEALTH RECORDS
PPTX
Engineering Ethics, Safety and Environment [Autosaved] (1).pptx
PPTX
Foundation to blockchain - A guide to Blockchain Tech
PDF
Embodied AI: Ushering in the Next Era of Intelligent Systems
PDF
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
PDF
BIO-INSPIRED HORMONAL MODULATION AND ADAPTIVE ORCHESTRATION IN S-AI-GPT
PDF
737-MAX_SRG.pdf student reference guides
PPTX
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
PPTX
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
PPTX
Sustainable Sites - Green Building Construction
PPTX
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
PDF
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
PDF
R24 SURVEYING LAB MANUAL for civil enggi
PDF
Operating System & Kernel Study Guide-1 - converted.pdf
PDF
PPT on Performance Review to get promotions
PPTX
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
PDF
composite construction of structures.pdf
PPTX
Internet of Things (IOT) - A guide to understanding
III.4.1.2_The_Space_Environment.p pdffdf
CH1 Production IntroductoryConcepts.pptx
PREDICTION OF DIABETES FROM ELECTRONIC HEALTH RECORDS
Engineering Ethics, Safety and Environment [Autosaved] (1).pptx
Foundation to blockchain - A guide to Blockchain Tech
Embodied AI: Ushering in the Next Era of Intelligent Systems
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
BIO-INSPIRED HORMONAL MODULATION AND ADAPTIVE ORCHESTRATION IN S-AI-GPT
737-MAX_SRG.pdf student reference guides
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
Sustainable Sites - Green Building Construction
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
R24 SURVEYING LAB MANUAL for civil enggi
Operating System & Kernel Study Guide-1 - converted.pdf
PPT on Performance Review to get promotions
FINAL REVIEW FOR COPD DIANOSIS FOR PULMONARY DISEASE.pptx
composite construction of structures.pdf
Internet of Things (IOT) - A guide to understanding

When symfony met promises