Re: Refactoring our IO multiplexing layer

From: Date: Tue, 17 Jun 2014 13:45:37 +0000
Subject: Re: Refactoring our IO multiplexing layer
Groups: php.internals 
Request: Send a blank email to internals+get-74946@lists.php.net to get a copy of this message
On 17 June 2014 12:05, Julien Pauli <jpauli@php.net> wrote: > So basically, the first question will be do we need it ? I feel very strongly that the answer here is: yes. > Second question will be : do we use, and then link against libevent > (or any other lib that could fit the need) , or do we develop our own > layer, based on the FPM layer which is pretty nicely done (just not > shareable elsewhere at the moment). I feel very strongly that the answer here is not libevent; it's libuv. I feel even stronger that rolling our own would be a colossal mistake. > And then, will people be interested by the RFC ? Can't speak for anyone other than myself, but: yes. TL;DR: We should use libuv, not libevent. Now let me tick off some further thoughts on the matter ... Philosophy ======== All IO operations should be non-blocking by default. It's trivial to block until completion if everything is non-blocking for simple use-cases but it's impossible to go in the other direction. By using a non-blocking model you allow *both* high-performance single-threaded concurrency *and* the simpler blocking model that has made PHP so easy to use (read: successful) over the years. It's critical that we retain the spirit (ease of use) of PHP going forward. If the API is designed correctly non-blocking IO will be a valuable performance option that doesn't infringe on traditional use-cases. Relative Performance =============== Most (all?) of the recent performance work has centered on improving language speed. This is a great thing, but IMO the PHP language is already *plenty* fast enough. The slowest part of the PHP request lifecycle is by far blocking IO. In this regard I think the HHVM work is tackling the absolute wrong problem. By way of example: I've written a full-featured HTTP/websocket server in *userland PHP* capable of serving ~50,000 HTTP requests/second with 10,000 simultaneous connected socket clients on a single box (can use either the existing pecl/libevent or php-uv extension as a backend). I repeat: the PHP language is not the bottleneck to web performance; it's the lack of built-in nbio functionality and the lack of a performant polling mechanism (epoll/kqueue/etc). Threading ======= First, I do not personally believe that threading should be exposed to userland. *However*, libuv exposes a cross-platform *non-blocking* threading API. Adopting libuv would allow php-src code to take advantage of a unified threading API internally without blocking the event loop or breaking existing code. To me this feature alone makes libuv the obvious choice for the IO backend. Also, if we ever did decide to expose threading in userland the groundwork would already exist. In particular, libuv already trivializes offloading work to a thread queue: http://nikhilm.github.io/uvbook/threads.html Process Control ============ This is a tangential benefit to implementing either libevent or libuv. Both libevent and libuv offer *cross-platform* process control. While this is a bit limited in Windows it *does allow* basic Ctrl+C interrupt handling and other graceful shutdown/cleanup opportunities. The current lack of such functionality severely limits the usefulness of PHP to write standalone programs that also work in Windows (because ext/pcntl is a no-go there). Just last week I added signal handling support to @chobie's excellent php-uv extension if you care to peruse how easy this is with libuv: https://github.com/chobie/php-uv/commit/1e32c246081a1b33a52c51045014c4440c6d0924 Misc ==== It's worth noting that Mozilla's Rust language is using libuv under the hood. Obviously, node.js is implemented on top of libuv as well. libuv is far more actively developed than libevent. Also, libuv offers a *huge* advantage over any other abstraction (that I'm aware of) in that it does all the heavy-lifting for IOCP in Windows. IOCP support would be an absolutely massive win for PHP in windows. Couple that with the built-in threading functionality and generally more robust featureset than libevent and libuv just seems like a no-brainer. Feel free to tell me I'm wrong and/or stupid but libuv seems like the only sensible option to me. P.S. I think that implementing/maintaining this stuff ourselves would be a really poor idea.

« previous php.internals (#74946) next »