php fibers
php fibers

A new PHP Fibers RFC is actually in voting process in the PHP internals, written by Aaron Piotrowski  and Niklas Keller. The new feature will provide high level concurrency support to PHP 8, but not intended to be used by applications developers, instead library and framework authors to provide an event loop and an asynchronous programming API. Basically you can think of fibers as threads or code blocks that can be paused and resumed.

As noted in the RFC, The Fiber API is not expected to be used directly in application-level code. Fibers provide a basic, low-level flow-control API to create higher-level abstractions that are then used in application code. They allow the creation of full-stack, interruptible functions that can be used to implement cooperative multitasking in PHP. These are also known as coroutines or green-threads.

The new RFC created a lots of wrangle in the PHP internals, why this feature should be in PHP, why it couldn’t be just in PECL ? Is this new feature only for Amphp, ReactPHP and Guzzle, or all other frameworks can implement it and profit from this new feature ? Lots of questions that have been asked and answered in the internals, a great discussion raised about the next generation of PHP.

What are PHP Fibers

So Fibers are interruptible functions that can be used to implement cooperative multitasking in PHP. It’s piece of block code that you can pause and resume, but as we previously mentioned it’s not expected from you to use this in your applications, rather for PHP Frameworks. Also note that this implementation is experimental, which mean “fibers would be compiled and available in all releases, but the documentation would denote that behavioral and API changes may be made in future minor releases , so use it at your own risk” as indicated Aaron Piotrowski.

The example below creates a new fiber and suspend it immediately with the string “fiber”. This string is returned from the call to $fiber->start(). The fiber is then resumed with the string “test”, which is returned from the call to Fiber::suspend().

$fiber = new Fiber(function (): void {
    $value = Fiber::suspend('fiber');
    echo "Value used to resume fiber: ", $value, "\n";
});
 
$value = $fiber->start();
 
echo "Value from fiber suspending: ", $value, "\n";
 
$fiber->resume('test');

The result of execution of this code will be :

Value from fiber suspending: fiber
Value used to resume fiber: test

Another example could be found on the RFC, show how to implement an event loop to poll a socket for incoming data. This could be useful to resume a fiber only when data becomes available on a socket, avoiding a blocking read. Writing this example without Fibers, the script would be unable to read from a socket before writing to it, as the call to fread() would block until data was available.

The chart below illustrates the execution flow between {main} and the { fiber }. Execution flow switches between fibers as Fiber::suspend() and Fiber->resume() are called or when a fiber terminates.

PHP Fibers Flow

Swoole and PHP Fibers

Tianfeng Han, founder of Swoole project, think that ext-fiber is more suitable as a PECL project. Coroutine and asynchronous IO is a new concurrency model, This is very different from blocking IO. according to him.

Twosee, who is core contributor to Swoole project and author of the Swow library (a Coroutine-based concurrency library for PHP), pointed that PHP Fibers are not compatible with Swoole due to issues he mentioned including : Switch notification, C extension support, Unsolvable blocking, CPU starvation,  Pure C coroutine, and finally the code about coroutine switching could be simplified.

The idea is that Fiber is an enhancement of Generator implementation introduced in PHP 5.5. So this is not a full support of concurrency in the PHP core, but just a step toward providing full async support in PHP, without conflicting with or restricting future additions.

Swoole have already Coroutine module and the previous PHP Fibers example could be written in Swoole as mentioned by Leo Cavalcante in twitter :

<?php declare(strict_types=1)

use Swoole\Coroutine as Fiber;

Fiber\run(static function(): void {
   $fiberId = Fiber::create(static function(): void {
      Fiber::suspend();
      echo "Fiber resumed \n";
   });

   echo "Fiber $fiberId suspended "\n";
   Fiber::resume($fiberId);
});

Tianfeng Han also proposed to discuss extensively 7 parts that he think are crucial to provide full concurrency support to PHP :

  • EventLoop API
  • Fiber/Coroutine/GreenThread
  • IO-Scheduler (Socket/FileSystem/ChildProcess/Signal/Timer/Stdout/Stdin)
  • CPU-Scheduler
  • Compatible with existing extesions&nbsp; (php_streams/ext-sockets/ext-redis/ext-mysqli/ext-pdo-mysql/ext-curl …) and builtin-functions (sleep/gethostbyname/proc_open/file_get_contents)
  • Service container. How to support php-fpm and provide a coroutine version of http server
  • Coroutine communication. How to pass messages between two coroutines

We don’t really think that language or culture is a barrier to make PHP better. The PHP community is and will remain always be open, and this is what’s making PHP not the best, but always great to getting things done !

RFC Voting ethics

Dan Ackroyd raised an important note in the emailing about putting pressure on vote off the list “Please don’t contact people off list putting pressure on them to vote in a particular way. It _really_ is not appreciated, no matter how well intentioned the sender thinks it is.”, he mentioned.

We are not sure who contacted who, but usually during voting process we usually avoid even talking about the RFC, but this one seems to be very special and raised lots of discussions here and there the reason why we could not avoid giving you this coverage. Also it’s important to read RFC etiquette to better understand the whole process.

What’s Next ?

The voting process will end by March 22, as for today the results are so far so good 36 Yes, 11 No. 2/3 are required to accept the RFC.

Read more about PHP Fibers RFC https://wiki.php.net/rfc/fibers
PHP Fibers discussion on PHP internals : https://externals.io/message/113419

LEAVE A REPLY

Please enter your comment!
Please enter your name here