Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pushing the limits of PHP with ReactPHP – why ReactPHP is awesome and why you should care (IPC17)

Pushing the limits of PHP with ReactPHP – why ReactPHP is awesome and why you should care (IPC17)

It’s 2017 and times have changed – yet PHP is still most often associated with your average product catalogue or blogging platform. In this talk you will learn that PHP’s huge ecosystem has way more to offer and PHP is not inferior at all to its evil cousin Node.js. You will learn about the core concepts of async PHP and why you too should care about ReactPHP being a real thing. The talk has a strong focus on sparking the idea that PHP can be way faster and more versatile than you probably thought. Bring along an open mind and through lots of examples and demos learn why what sounds crazy at first might soon be a valuable addition in your toolbox.

Christian Lück
PRO

June 01, 2017
Tweet

More Decks by Christian Lück

Other Decks in Programming

Transcript

  1. pushing the limits with ReactPHP
    why ReactPHP is awesome and why YOU should care

    View Slide

  2. Agenda
    - Hello!
    - PHP, the web of the ‘90s?
    - Enter React
    - Core components
    - Examples and demo time
    - Conclusions
    2

    View Slide

  3. Hello!
    3

    View Slide

  4. $ whoami
    Christian Lück
    4

    View Slide

  5. $ whoami
    Christian Lueck
    5

    View Slide

  6. $ whoami
    Christian Lueck
    6

    View Slide

  7. $ whoami
    Christian Lueck
    @clue
    7

    View Slide

  8. $ whoami
    Christian Lueck
    @another_clue
    8

    View Slide

  9. $ whoami
    Christian Lueck
    @another_clue
    passionate about pushing the limits
    9

    View Slide

  10. $ whoami
    Christian Lueck
    @another_clue
    passionate about pushing the limits
    freelance software engineer 10

    View Slide

  11. Who are you?
    11
    now that you know me…

    View Slide

  12. Who are you?
    12
    now that you know me…
    - PHP developers?
    - architecs / engineers?

    View Slide

  13. Who are you?
    13
    now that you know me…
    - PHP developers?
    - architecs / engineers?
    - know React?

    View Slide

  14. 14

    View Slide

  15. The other React™
    15

    View Slide

  16. The REAL React™
    16

    View Slide

  17. PHP, the web of the ‘90s?
    17

    View Slide

  18. PHP and the web of the ‘90s
    - traditional LAMP stack
    - Request-Response-Cycle
    18
    Apache
    Client PHP MySQL

    View Slide

  19. PHP and the web of the ‘90s
    - traditional LAMP stack
    - Request-Response-Cycle
    - PHP is too slow?
    - We sure can improve this…
    19
    Apache
    Client PHP MySQL

    View Slide

  20. PHP and the web of the ‘90s
    - traditional LAMP stack
    - Request-Response-Cycle
    - PHP is too slow?
    - We sure can improve this…
    20
    Apache
    Client PHP MySQL
    Apache
    Client
    FPM
    MySQL
    PHP
    PHP

    View Slide

  21. PHP and the web of the ‘90s
    - traditional LAMP stack
    - Request-Response-Cycle
    - PHP is too slow?
    - We sure can improve this…
    21
    Apache
    Client PHP MySQL
    Apache
    Client
    FPM
    MySQL
    PHP
    PHP
    nginx
    Client
    FPM
    MySQL
    PHP
    PHP

    View Slide

  22. PHP and the web of the ‘90s
    - traditional LAMP stack
    - Request-Response-Cycle
    - PHP is too slow?
    - We sure can improve this…
    22
    Apache
    Client PHP MySQL
    Apache
    Client
    FPM
    MySQL
    PHP
    PHP
    nginx
    Client
    FPM
    MySQL
    PHP
    PHP
    nginx
    Client
    FPM
    memcache
    PHP
    PHP
    MySQL

    View Slide

  23. PHP may not be pretty…
    23

    View Slide

  24. PHP may not be pretty…
    but it gets the job done!
    24

    View Slide

  25. Knock knock!
    Who’s there?
    25

    View Slide

  26. Knock knock!
    2017!
    Who’s there?
    26

    View Slide

  27. Knock knock!
    2017!
    - Separation of concerns
    (Frontend↔Backend)
    - HTTP APIs (RESTful)
    - Integration with 3rd parties
    - Live-Data (ticker)
    - CLI tools
    Who’s there?
    27

    View Slide

  28. nodejs?
    28

    View Slide

  29. no js!
    29

    View Slide

  30. Enter React!
    30

    View Slide

  31. What is React?
    31

    View Slide

  32. What is React?
    non-blocking I/O
    32

    View Slide

  33. What is React?
    non-blocking I/O
    event-driven
    33

    View Slide

  34. What is React?
    non-blocking I/O
    event-driven
    async
    34

    View Slide

  35. 100%
    35

    View Slide

  36. 100%
    pure PHP
    36

    View Slide

  37. 100%
    pure PHP
    no extensions
    37

    View Slide

  38. 100%
    pure PHP
    no extensions
    no magic
    38

    View Slide

  39. What does that even mean?!
    39

    View Slide

  40. the idea
    40

    View Slide

  41. the idea
    calculations are fast
    41

    View Slide

  42. the idea
    calculations are fast
    I/O is slow
    42

    View Slide

  43. I/O is everywhere
    43

    View Slide

  44. I/O is everywhere
    third party HTTP APIs (RESTful, SOAP, you name it…)
    44

    View Slide

  45. I/O is everywhere
    third party HTTP APIs (RESTful, SOAP, you name it…)
    mysql, postgres
    45

    View Slide

  46. I/O is everywhere
    third party HTTP APIs (RESTful, SOAP, you name it…)
    mysql, postgres
    filesystem I/O (session files)
    46

    View Slide

  47. I/O is everywhere
    third party HTTP APIs (RESTful, SOAP, you name it…)
    mysql, postgres
    filesystem I/O (session files)
    redis, memcache 47

    View Slide

  48. 48
    Source: Latency Numbers Every Programmer Should Know: https://gist.github.com/jboner/2841832
    CPU vs I/O

    View Slide

  49. I/O is slow!
    49

    View Slide

  50. I/O is slow!
    So why wait?
    50

    View Slide

  51. This is React
    51

    View Slide

  52. This is React
    52
    Start multiple I/O operations (non-blocking)

    View Slide

  53. This is React
    53
    Start multiple I/O operations (non-blocking)
    Get notified when something happens (react)

    View Slide

  54. This is React
    54
    Start multiple I/O operations (non-blocking)
    Get notified when something happens (react)
    Don’t waste time waiting

    View Slide

  55. What React is not
    55

    View Slide

  56. What React is not
    - React is not black magic / vodoo
    - Does not make your code faster magically
    56

    View Slide

  57. What React is not
    - React is not black magic / vodoo
    - Does not make your code faster magically
    - React is not a framework
    - Indepentent components (libraries)
    57

    View Slide

  58. What React is not
    - React is not black magic / vodoo
    - Does not make your code faster magically
    - React is not a framework
    - Indepentent components (libraries)
    - React is not a replacement for your favorite framework
    - Symfony is here to stay
    58

    View Slide

  59. What React is not
    - React is not black magic / vodoo
    - Does not make your code faster magically
    - React is not a framework
    - Indepentent components (libraries)
    - React is not a replacement for your favorite framework
    - Symfony is here to stay
    - React is not the new buzz
    - React is here to stay as well (started in 2012)
    59

    View Slide

  60. React core components
    60

    View Slide

  61. React Core components
    - Event loop (reactor)
    - Streams
    - Promises
    61

    View Slide

  62. Event loop
    Consumers
    - THE core, low-level component
    62

    View Slide

  63. Event loop
    Consumers
    - THE core, low-level component
    - Create an instance
    - Just use the Factory
    - Additional extensions for bigger payloads
    - something inbetween…
    - just pass the $loop around
    - Start running
    - keeps running forever
    - unless stopped or done
    63

    View Slide

  64. Event loop
    Consumers
    - THE core, low-level component
    - Create an instance
    - Just use the Factory
    - Additional extensions for bigger payloads
    - something inbetween…
    - just pass the $loop around
    - Start running
    - keeps running forever
    - unless stopped or done
    64
    $loop = Factory::create();
    // something inbetween
    // pass the $loop around to all components
    $loop->run();

    View Slide

  65. Event loop
    Implementors
    - Reactor pattern (hence the name)
    65

    View Slide

  66. Event loop
    Implementors
    - Reactor pattern (hence the name)
    - start timers
    - once
    - periodic
    - ticks
    66
    $loop->addTimer(0.5, function () {
    echo ‘world’;
    });
    $loop->addTimer(0.3, function () {
    echo ‘hello’;
    });

    View Slide

  67. Event loop
    Implementors
    - Reactor pattern (hence the name)
    - start timers
    - once
    - periodic
    - ticks
    - wait for stream resources to become
    - readable
    - writable
    67
    $loop->addTimer(0.5, function () {
    echo ‘world’;
    });
    $loop->addTimer(0.3, function () {
    echo ‘hello’;
    });
    $loop->addReadStream($stream, $fn);
    $loop->addWriteStream($stream, $fn);

    View Slide

  68. Streams
    - Process large strings in chunks as they happen (think downloads)
    - Types
    - Readable (e.g. STDIN pipe)
    - Writable (e.g. STDOUT pipe)
    - Duplex (e.g. TCP/IP connection)
    68

    View Slide

  69. Streams
    - interfaces, events and listeners:
    69
    $dest->write(‘hello’);
    $source->on(‘data’, function ($data) {
    var_dump($data);
    });
    $source->on(‘close’, function () {
    echo ‘stream closed’;
    });

    View Slide

  70. Streams
    - interfaces, events and listeners:
    70
    $dest->write(‘hello’);
    $source->on(‘data’, function ($data) {
    var_dump($data);
    });
    $source->on(‘close’, function () {
    echo ‘stream closed’;
    });
    $source->pipe($gunzip)->pipe($badwords)->pipe($dest);

    View Slide

  71. Promises
    - Placeholder for a single future result
    - Possible states:
    - pending
    - fulfilled (successfully resolved)
    - rejected (Exception occured)
    71

    View Slide

  72. Promises
    - no more imperative code flow
    - instead (tell, don’t ask)
    72
    $a->then($fulfilled = null, $rejected = null);
    $a->then(‘process’);
    $a->then(‘process’, ‘var_dump’);

    View Slide

  73. Examples and demo time!
    73

    View Slide

  74. Socket server
    74
    react/socket
    - THE canonical chat example
    - broadcast all incoming msgs

    View Slide

  75. Socket server
    75
    react/socket
    - THE canonical chat example
    - broadcast all incoming msgs
    - run example server
    - connect via telnet:
    $ telnet ipc.clue.engineering 6001

    View Slide

  76. 76

    View Slide

  77. HTTP client
    77
    clue/buzz-react
    - Simple HTTP requests
    - inspired by kriswallsmith/buzz
    - PSR-7 compatible

    View Slide

  78. HTTP client
    78
    clue/buzz-react
    - Simple HTTP requests
    - inspired by kriswallsmith/buzz
    - PSR-7 compatible
    - Promises and Streams
    - It’s fast…

    View Slide

  79. HTTP client
    79
    clue/buzz-react
    - Simple HTTP requests
    - inspired by kriswallsmith/buzz
    - PSR-7 compatible
    - Promises and Streams
    - It’s fast…
    - benchmarks in following slides about
    clue/docker-react

    View Slide

  80. Packagist API
    clue/packagist-api-react
    - get information about any
    Composer package
    - simple, Promise-based
    - lightweight wrapper between
    - KnpLabs/packagist-api
    - clue/buzz-react
    80

    View Slide

  81. Packagist API
    clue/packagist-api-react
    - get information about any
    Composer package
    - simple, Promise-based
    - lightweight wrapper between
    - KnpLabs/packagist-api
    - clue/buzz-react
    81
    - see its examples
    $ php examples/search.php

    View Slide

  82. Docker client
    clue/docker-react
    - Run apps in isolated containers
    - “build, ship and run, anywhere”
    - Controlled through HTTP API
    - Promises and Streams
    82

    View Slide

  83. Docker client
    clue/docker-react
    - Run apps in isolated containers
    - “build, ship and run, anywhere”
    - Controlled through HTTP API
    - Promises and Streams
    83
    - see its promise examples
    $ php examples/info.php
    - see its streaming examples
    $ php examples/benchmark-exec.php

    View Slide

  84. 700 MiB/s
    84

    View Slide

  85. 700 MiB/s
    85
    dockerd maxed out
    PHP not

    View Slide

  86. HTTP server
    react/http
    - Pure PHP, with
    no additional webserver
    - standard PSR-7 interfaces
    86

    View Slide

  87. HTTP server
    react/http
    - Pure PHP, with
    no additional webserver
    - standard PSR-7 interfaces
    - Lots of third-party integrations
    with traditional frameworks
    (symfony, slim, silex, PIMF etc.)
    87

    View Slide

  88. 5k requests/s
    88

    View Slide

  89. 5k requests/s
    89
    this is a local single core benchmark!

    View Slide

  90. 5k requests/s
    90
    this is a local single core benchmark!
    dual core i3 => 10k requests/s

    View Slide

  91. 5k requests/s
    91
    this is a local single core benchmark!
    dual core i3 => 10k requests/s
    36M requests/h

    View Slide

  92. Server sent events
    clue/sse-react
    - Server sent events (SSE)
    - aka. EventSource (browser API)
    - Streaming events to browser
    - limited browser support
    92

    View Slide

  93. Server sent events
    clue/sse-react
    - Server sent events (SSE)
    - aka. EventSource (browser API)
    - Streaming events to browser
    - limited browser support
    93
    - see examples connecting to initial chat
    $ php examples/chat-server.php
    - open browser:
    http://ipc.clue.engineering:7000/

    View Slide

  94. 94

    View Slide

  95. Websocket server
    cboden/ratchet
    - Async WebSocket server
    - bidirectional data flow between
    browser and server
    - better browser support
    95

    View Slide

  96. Redis client
    96
    clue/redis-react
    - Redis is a fast in-memory DB
    - very simple commands
    - very simple protocol
    - pipelined, Promise-based

    View Slide

  97. Redis client
    97
    clue/redis-react
    - Redis is a fast in-memory DB
    - very simple commands
    - very simple protocol
    - pipelined, Promise-based
    - see its examples
    $ php examples/incr.php

    View Slide

  98. Redis server
    98

    View Slide

  99. Redis server
    99
    - Official Redis is written in C

    View Slide

  100. Redis server
    100
    clue/php-redis-server
    - Official Redis is written in C
    - Reimplementation is pure PHP

    View Slide

  101. Redis server
    101
    clue/php-redis-server
    - Official Redis is written in C
    - Reimplementation is pure PHP
    - Very simple to add commands

    View Slide

  102. Redis server
    102
    clue/php-redis-server
    - Official Redis is written in C
    - Reimplementation is pure PHP
    - Very simple to add commands
    - How fast could PHP possibly be?
    Let’s see…

    View Slide

  103. Redis server
    103
    clue/php-redis-server
    - Official Redis is written in C
    - Reimplementation is pure PHP
    - Very simple to add commands
    - How fast could PHP possibly be?
    Let’s see…
    - see its bin
    $ php bin/redis-server.php
    - test via clue/redis-react
    - test via official redis CLI
    - run official redis benchmark during talk:
    - official server: ~90k OP/s
    - PHP server: ~50k OP/s

    View Slide

  104. 50k OP/s
    104

    View Slide

  105. 50k OP/s
    pure PHP
    who needs native code anyway?
    105

    View Slide

  106. Redis framework
    106
    clue/php-redis-framework
    - Development preview
    - Very simple to add custom
    commands

    View Slide

  107. Redis framework
    107
    clue/php-redis-framework
    - Development preview
    - Very simple to add custom
    commands
    - run example server
    $ php examples/11-beer.php
    - connect via telnet:
    $ telnet IP 9000

    View Slide

  108. 108

    View Slide

  109. UPnP
    clue/ssdp-react
    - Univeral Plug and Play (UPnP)
    - Simple Service Discovery
    Protocol (SSDP)
    - dicover UPnP-enabled devices
    - printers
    - routers
    - multi media devices
    109

    View Slide

  110. UPnP
    clue/ssdp-react
    - Univeral Plug and Play (UPnP)
    - Simple Service Discovery
    Protocol (SSDP)
    - dicover UPnP-enabled devices
    - printers
    - routers
    - multi media devices
    110
    - see its examples
    $ php examples/search.php

    View Slide

  111. Zenity
    clue/zenity-react
    - PHP desktop GUI applications
    - very simple, Promise-based
    111

    View Slide

  112. Zenity
    clue/zenity-react
    - PHP desktop GUI applications
    - very simple, Promise-based
    112
    - see its simple examples
    $ php examples/01-dialog.php
    - see its more realistic examples
    $ php examples/06-menu.php
    $ php examples/03-progress-pulsate.php
    $ php examples/03-progress-random.php

    View Slide

  113. 113

    View Slide

  114. 114

    View Slide

  115. 115

    View Slide

  116. many, MANY more third-party projects:
    https://github.com/reactphp/react/wiki/Users
    116

    View Slide

  117. Conclusions
    117

    View Slide

  118. Conclusions
    118
    - React is a real deal and here to stay
    - React is stable and production ready
    - predictable releases
    - but possibly feature-incomplete (check open issues)

    View Slide

  119. Conclusions
    119
    - React is a real deal and here to stay
    - React is stable and production ready
    - predictable releases
    - but possibly feature-incomplete (check open issues)
    - React does not make your code faster magically

    View Slide

  120. Conclusions
    120
    - React is a real deal and here to stay
    - React is stable and production ready
    - predictable releases
    - but possibly feature-incomplete (check open issues)
    - React does not make your code faster magically
    - Consider using React whenever you’re having to wait
    - Consider using React whenever you’re accessing the network

    View Slide

  121. PHP is faster than you
    probably thought
    121

    View Slide

  122. PHP is more versatile than you
    probably thought
    122

    View Slide

  123. Need help? Want to help?
    - check each component’s README
    - check open issues
    123

    View Slide

  124. Need help? Want to help?
    - check each component’s README
    - check open issues
    - join #reactphp on irc.freenode.org
    - tweet @ReactPHP or #reactphp
    124

    View Slide

  125. Need help? Want to help?
    - check each component’s README
    - check open issues
    - join #reactphp on irc.freenode.org
    - tweet @ReactPHP or #reactphp
    - Talk to me
    125

    View Slide

  126. Need help? Want to help?
    - check each component’s README
    - check open issues
    - join #reactphp on irc.freenode.org
    - tweet @ReactPHP or #reactphp
    - Talk to me
    Did I mention I’m available?
    126

    View Slide

  127. // thank you!
    $loop->stop();
    127
    @another_clue – https://lueck.tv/

    View Slide

  128. Avoid blocking!
    - The loop must not be blocked
    128

    View Slide

  129. Avoid blocking!
    - The loop must not be blocked
    - Many functions / lib assume blocking by default
    - Anything >1ms should be reconsidered
    129

    View Slide

  130. Avoid blocking!
    - The loop must not be blocked
    - Many functions / lib assume blocking by default
    - Anything >1ms should be reconsidered
    - Alternatives
    - Single result: Promises
    - Evented: Streams
    130

    View Slide

  131. Avoid blocking!
    - The loop must not be blocked
    - Many functions / lib assume blocking by default
    - Anything >1ms should be reconsidered
    - Alternatives
    - Single result: Promises
    - Evented: Streams
    - Need a blocking function?
    - Fork off!
    - Use IPC
    131

    View Slide

  132. Avoid blocking!
    - The loop must not be blocked
    - Many functions / lib assume blocking by default
    - Anything >1ms should be reconsidered
    - Alternatives
    - Single result: Promises
    - Evented: Streams
    - Need a blocking function?
    - Fork off!
    - Use IPC
    132
    Pay attention:
    - PDO, mysql etc.
    - file system access
    - network access
    - third-party APIs

    View Slide

  133. Integration with traditional environments
    133
    integrating async into sync is easy

    View Slide

  134. Integration with traditional environments
    134
    integrating async into sync is easy
    - just run the loop until you’re done
    - see clue/block-react

    View Slide

  135. Integration with traditional environments
    135
    integrating async into sync is easy
    - just run the loop until you’re done
    - see clue/block-react
    integrating sync into async is hard

    View Slide

  136. Integration with traditional environments
    136
    integrating async into sync is easy
    - just run the loop until you’re done
    - see clue/block-react
    integrating sync into async is hard
    - often requires async rewrite
    - consider forking instead

    View Slide