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

From Generator to Fiber the Road to Coroutine in PHP

From Generator to Fiber the Road to Coroutine in PHP

COSCUP 2022

Albert Chen

December 20, 2022
Tweet

More Decks by Albert Chen

Other Decks in Programming

Transcript

  1. From Generator to Fiber The Road to Coroutine in PHP

    @COSCUP 2022 Albert Chen
  2. 02 Blocking and Async I/O in PHP Outline 01 I/O

    Models in Linux 03 What is Generator? 04 What is Fiber in PHP 8.1? 05 How to use Async I/O with Coroutine? 07 Q&A 06 Coroutines in Swoole
  3. Read/Write Read/Write (O_NONBLOCK) I/O Multiplexing (select/poll/epoll) AIO I/O Models in

    Linux Simplified Matrix of Linux I/O Models Blocking Non-Blocking Synchronous Asynchronous (https://developer.ibm.com/articles/l-async)
  4. I/O Models in Linux Synchronous Blocking I/O (https://developer.ibm.com/articles/l-async)

  5. I/O Models in Linux Synchronous Non-Blocking I/O (https://developer.ibm.com/articles/l-async)

  6. I/O Models in Linux Asynchronous Blocking I/O (https://developer.ibm.com/articles/l-async)

  7. I/O Models in Linux Asynchronous Non-Blocking I/O (https://developer.ibm.com/articles/l-async)

  8. I/O Models in Linux Comparison of the I/O Models (https://rickhw.github.io/2019/02/27/ComputerScience/IO-Models)

  9. select poll epoll Data Structue Array Link List Hash Table

    Big O O(n) O(n) O(1) FD Limit 1024 (x86) 2048 (x64) Unlimited Unlimited I/O Multiplexing I/O Multiplexing in Linux
  10. I/O Multiplexing I/O Multiplexing in Linux (http://daemonforums.org/showthread.php?t=2124)

  11. Blocking I/O in PHP All I/O functions in PHP are

    born to be synchronous Easy for developers to understand Less-efficient for utilization of CPU usage
  12. sleep file_get_contents shell_exec end Blocking I/O in PHP 1s 3s

    3s process idle + + process idle process idle 7s =
  13. 1s worker 1s worker 1s worker Blocking I/O in PHP

    If one request takes 1s in I/O waiting Each worker can handle only one request and the same time Concurrency in PHP depends on worker numbers Context switch between processes are expensive! request request request
  14. Asynchronous I/O in PHP The simplest but worst-performant solution in

    PHP spatie/async package (needs pcntl and posix extensions)
  15. Asynchronous I/O in PHP The simplest but worst-performant solution in

    PHP spatie/async package (needs pcntl and posix extensions) worker process process fork fork
  16. Asynchronous I/O in PHP ReactPHP

  17. Asynchronous I/O in PHP ReactPHP

  18. Asynchronous I/O in PHP Amp

  19. Asynchronous I/O in PHP Amp

  20. Asynchronous I/O in PHP Async I/O Extensions in PHP ext-event:

    libevent wrapper ext-ev: libev wrapper ext-uv: libuv wrapper Both ReactPHP and Amp support these extensions as event-loop drivers
  21. Asynchronous I/O in PHP Event Loop Event Queue Stream Stream

    Stream Stream Stream Event Loop callbacks
  22. Asynchronous I/O in PHP Event Loop in ReactPHP

  23. Asynchronous I/O in PHP Event Loop in ReactPHP

  24. Generator Supported from PHP 5.4 Generator provides an easy way

    to implement simple iterators Generator allows you to write code that uses foreach to iterate over a set of data without needing to build an array in memory Generator can yield as many times as it needs to provide the values to be iterated over (From official PHP manual)
  25. Generator Reading large file with Generator Regular Version Generator Version

    (https://clouding.city/php/generator)
  26. Generator Generators, also known as semi-coroutines, are a subset of

    coroutines Coroutines can control where execution continues immediately after they yield, while Generators cannot, instead transferring control back to the generator's caller The yield statement in a generator does not specify a coroutine to jump to, but rather passes a value back to a parent routine (From Wikipedia)
  27. Generators yield iteration Generator Producer Consumer Pub/Sub Pattern two way

    data transfer
  28. Generator Two Way Data Transfer in Generator ? (https://www.npopov.com/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html)

  29. Generator Two Way Data Transfer in Generator yield1 ret1 yield2

    ret2 NULL the first var_dump in gen the var_dump of the ->send() again from within gen the return value of ->send() (https://www.npopov.com/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html)
  30. Generator Generator in ReactPHP's Coroutine (https://github.com/reactphp/async)

  31. Generator Generator in ReactPHP's Coroutine (https://github.com/reactphp/async/blob/4.x/src/functions.php)

  32. Generator Generator in ReactPHP's Coroutine (https://github.com/reactphp/async/blob/4.x/src/functions.php)

  33. Generator Generator in Amp's Coroutine (https://amphp.org/http-client)

  34. Generator Generator in Amp's Coroutine (https://github.com/amphp/amp/blob/master/lib/Coroutine.php)

  35. Generator Generator in Amp's Coroutine (https://github.com/amphp/amp/blob/master/lib/Coroutine.php)

  36. Fiber New feature in PHP 8.1 Submitted and developed by

    Amp Unlike stack-less Generators, each Fiber has its own call stack, allowing them to be paused within deeply nested function calls Execution may be interrupted anywhere in the call stack using Fiber::suspend() Once suspended, execution of the fiber may be resumed with any value using Fiber::resume() (From official PHP manual)
  37. Fiber Execution in Fiber (https://php.watch/versions/8.1/fibers) Sequential Fiber

  38. Fiber Fiber Class

  39. Fiber Basic Usage ?

  40. Fiber Basic Usage fiber start fiber suspend fiber continue done

  41. Fiber Basic Usage ?

  42. Fiber Basic Usage start fiber 1 end fiber 1 start

    fiber 2 end fiber 2 done
  43. Fiber Fibers don't make blocking code become non-blocking magically!

  44. Fiber Basic Usage ?

  45. Fiber Basic Usage fiber start 0 1 2 3 .........

  46. Fiber Fibers only support Cooperative Scheduling for I/O-bound tasks

  47. Fiber Fiber in ReactPHP (https://github.com/reactphp/async#async)

  48. Fiber Fiber in ReactPHP (https://github.com/reactphp/async/blob/4.x/src/functions.php)

  49. Fiber Fiber in ReactPHP (https://github.com/reactphp/async/blob/4.x/src/functions.php)

  50. Fiber Fiber in Amp (https://github.com/amphp/http-client/blob/v5/examples/concurrency/1-concurrent-fetch.php)

  51. Fiber Fiber in Amp (https://github.com/amphp/amp/blob/v3/src/functions.php)

  52. Fiber Fiber in Amp (https://github.com/revoltphp/event-loop/blob/main/src/EventLoop/FiberLocal.php)

  53. Fiber Both ReactPHP and amp(3.0 beta) support Fiber now A

    comprehensive coroutine rather than semi-coroutine Eliminates yield statement for coroutines Fiber doesn't turn your code into non-blocking magically, traditional blocking code has to be rewritten for asynchronous I/O Help not too much for most of developers Fiber provides only bare minimum required to allow user code to implement full-stack coroutines in PHP Fiber doesn't support Preemptive Scheduling yet
  54. Questions What's the difference between Asynchronous and Coroutine? What's the

    difference between Generator and Fiber? How to turn Blocking I/O stream turning into Non-Blocking? What is Event Loop? Is it required for Asynchronous? What's the benefits of Coroutine? Is Asynchronous a must for Coroutine? How to make built-in Blocking I/O functions Asynchronous? Can Asynchronous I/O be integrated with traditional Blocking I/O environment? (e.g. PHP-FPM)
  55. Coroutine in Swoole Basic Usage ?

  56. Coroutine in Swoole Basic Usage start coro 1 start to

    resume 1 @1 resume coro 1 @1 start to resume 1 @2 resume coro 1 @2 main
  57. Coroutine in Swoole Coroutine for Blocking I/O ?

  58. Coroutine in Swoole Coroutine for Blocking I/O coroutine start 114.45.154.86

    coroutine end main
  59. Coroutine in Swoole Coroutine for Blocking I/O ?

  60. Coroutine in Swoole Coroutine for Blocking I/O coroutine start main

    xxx.xxx.xxx.xxx coroutine end
  61. Coroutine in Swoole Preemptive Scheduling ?

  62. Coroutine in Swoole Preemptive Scheduling

  63. Coroutine in Swoole Preemptive Scheduling ?

  64. Coroutine in Swoole Fatal error: Uncaught Exception: 12.5ms end in

    xxx Stack trace: #0 {main} thrown in xxx Preemptive Scheduling
  65. Coroutine in Swoole Channel ?

  66. Coroutine in Swoole Channel [coroutine 3] int(0) [coroutine 2] -

    0 [coroutine 3] int(1) [coroutine 2] - 1 [coroutine 3] ......
  67. Coroutine in Swoole Swoole implements its full coroutine features Built-in

    Blocking I/O functions can be replaced to Non-Blocking I/O automatically if hook flags are set Swoole supports Preemptive Scheduling for CPU-bound tasks Swoole Provides CSP Model for Coroutine Communications like in GoLang Yields and resumes take place behind the scenes for I/O functions switching
  68. Q&A