Successfully reported this slideshow.
Your SlideShare is downloading. ×

From Generator to Fiber the Road to Coroutine in PHP

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 69 Ad
Advertisement

More Related Content

Similar to From Generator to Fiber the Road to Coroutine in PHP (20)

Recently uploaded (20)

Advertisement

From Generator to Fiber the Road to Coroutine in PHP

  1. 1. From Generator to Fiber The Road to Coroutine in PHP @COSCUP 2022 Albert Chen
  2. 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. 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. 4. I/O Models in Linux Synchronous Blocking I/O (https://developer.ibm.com/articles/l-async)
  5. 5. I/O Models in Linux Synchronous Non-Blocking I/O (https://developer.ibm.com/articles/l-async)
  6. 6. I/O Models in Linux Asynchronous Blocking I/O (https://developer.ibm.com/articles/l-async)
  7. 7. I/O Models in Linux Asynchronous Non-Blocking I/O (https://developer.ibm.com/articles/l-async)
  8. 8. I/O Models in Linux Comparison of the I/O Models (https://rickhw.github.io/2019/02/27/ComputerScience/IO-Models)
  9. 9. 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
  10. 10. sleep file_get_contents shell_exec end Blocking I/O in PHP 1s 3s 3s process idle + + process idle process idle 7s =
  11. 11. 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
  12. 12. Asynchronous I/O in PHP The simplest but worst-performant solution in PHP spatie/async package (needs pcntl and posix extensions)
  13. 13. 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
  14. 14. Asynchronous I/O in PHP ReactPHP
  15. 15. Asynchronous I/O in PHP ReactPHP
  16. 16. Asynchronous I/O in PHP Amp
  17. 17. Asynchronous I/O in PHP Amp
  18. 18. 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
  19. 19. select poll epoll Data Structue Array Linked List Red–Black Tree Big O O(n) O(n) O(log(n)) FD Limit 1024 (x86) 2048 (x64) Unlimited Unlimited Asynchronous I/O in PHP I/O Multiplexing in Linux
  20. 20. Asynchronous I/O in PHP I/O Multiplexing in Linux (http://daemonforums.org/showthread.php?t=2124)
  21. 21. Asynchronous I/O in PHP Event Loop Event Queue Stream Stream Stream Stream Stream Event Loop callbacks
  22. 22. Asynchronous I/O in PHP Event Loop in ReactPHP
  23. 23. Asynchronous I/O in PHP Event Loop in ReactPHP
  24. 24. Generator Supported since PHP 5.5 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. 25. Generator Reading large file with Generator Regular Version Generator Version (https://clouding.city/php/generator)
  26. 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 A PHP based Coroutine Scheduler needs to implemented for stackful coroutine (From Wikipedia)
  27. 27. Generators yield iteration Generator two way data transfer Two Way Data Transfer in Generator
  28. 28. Generator Two Way Data Transfer in Generator ? (https://www.npopov.com/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html)
  29. 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. 30. Generator Generator in ReactPHP's Coroutine (https://github.com/reactphp/async)
  31. 31. Generator Generator in ReactPHP's Coroutine (https://github.com/reactphp/async/blob/4.x/src/functions.php)
  32. 32. Generator Generator in ReactPHP's Coroutine (https://github.com/reactphp/async/blob/4.x/src/functions.php)
  33. 33. Generator Generator in Amp's Coroutine (https://amphp.org/http-client)
  34. 34. Generator Generator in Amp's Coroutine (https://github.com/amphp/amp/blob/master/lib/Coroutine.php)
  35. 35. Generator Generator in Amp's Coroutine (https://github.com/amphp/amp/blob/master/lib/Coroutine.php)
  36. 36. Generator Both ReactPHP and Amp use Promise and Generator for Coroutine Generators yield promise Event Loop Coroutines subscribe send/throw
  37. 37. Fiber New feature in PHP 8.1 Submitted and developed by Amp Unlike stackless 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)
  38. 38. Fiber Execution in Fiber (https://php.watch/versions/8.1/fibers) Sequential Fiber
  39. 39. Fiber Fiber Class
  40. 40. Fiber Basic Usage ?
  41. 41. Fiber Basic Usage fiber start fiber suspend fiber continue done the first echo in fiber value from fiber suspend value from fiber resume end message
  42. 42. Fiber Basic Usage ?
  43. 43. Fiber Basic Usage start fiber 1 end fiber 1 start fiber 2 end fiber 2 done block here block here
  44. 44. Fiber Fibers don't make Blocking code become Non-Blocking magically!
  45. 45. Fiber Basic Usage ?
  46. 46. Fiber Basic Usage fiber start 0 1 2 3 ......... fiber never suspends
  47. 47. Fiber Fibers only support Cooperative Scheduling for I/O-bound tasks
  48. 48. Fiber Fiber in ReactPHP (https://github.com/reactphp/async#async)
  49. 49. Fiber Fiber in ReactPHP (https://github.com/reactphp/async/blob/4.x/src/functions.php)
  50. 50. Fiber Fiber in ReactPHP (https://github.com/reactphp/async/blob/4.x/src/functions.php)
  51. 51. Fiber Fiber in Amp (https://github.com/amphp/http-client/blob/v5/examples/concurrency/1-concurrent-fetch.php)
  52. 52. Fiber Fiber in Amp (https://github.com/amphp/amp/blob/v3/src/functions.php)
  53. 53. Fiber Fiber in Amp (https://github.com/revoltphp/event-loop/blob/main/src/EventLoop/FiberLocal.php)
  54. 54. Fiber Both ReactPHP and amp(v3 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 with 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
  55. 55. Coroutine in Swoole Basic Usage ?
  56. 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. 57. Coroutine in Swoole Coroutine for Blocking I/O ?
  58. 58. Coroutine in Swoole Coroutine for Blocking I/O coroutine start xxx.xxx.xxx.xxx coroutine end main block here
  59. 59. Coroutine in Swoole Coroutine for Blocking I/O ?
  60. 60. Coroutine in Swoole Coroutine for Blocking I/O coroutine start main xxx.xxx.xxx.xxx coroutine end auto yield auto resume
  61. 61. Coroutine in Swoole Preemptive Scheduling ?
  62. 62. Coroutine in Swoole Preemptive Scheduling infinite loop
  63. 63. Coroutine in Swoole Preemptive Scheduling ?
  64. 64. Coroutine in Swoole Fatal error: Uncaught Exception: 12.5ms end in xxx Stack trace: #0 {main} thrown in xxx Preemptive Scheduling
  65. 65. Coroutine in Swoole Channel ?
  66. 66. Coroutine in Swoole Channel [coroutine 3] int(0) [coroutine 2] - 0 [coroutine 3] int(1) [coroutine 2] - 1 [coroutine 3] ...... second coroutine second coroutine second coroutine popped value popped value first coroutine first coroutine
  67. 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. 68. 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)
  69. 69. Q&A

×