hi Aaron,
- Better support long-running, async-based, microservices-focused execution model. It's probably no secret that one of the key reasons Node is gaining popularity is because it can handle a huge number of concurrent connections issuing relatively lightweight requests very efficiently - which is a good match for modern microservices based architectures. There are already several projects available for PHP that aim to provide similar functionality - most notably ReactPHP and more recently Swoole.
The main thing that is missing is that most of PHP's IO doesn't support async execution. What I think we should do is add as much support for async IO as possible across the various extensions and streams - so that using something like Swoole would become practical for more use cases. More specifically - the goal would be to provide extension authors with mechanisms that they can use to make their extensions/functions optionally asynchronous, without having to tackle the job entirely on their own. While we've done some research into this area, it requires a lot more research - but I'm cautiously optimistic that it can be done. We would potentially want to use libuv for this task, and potentially rewrite or otherwise refactor parts of the PHP streams system.
Regarding async, are you referring to the Fiber extension? In my opinion, fibers would be the best approach for async in PHP. After using async/await in other languages, it doesn't offer a significant gain over what's already possible in PHP with generator-based coroutines in Amp. Using the fiber extension and a green-thread library that resumes fibers based on promise resolution [1], we've been able to write async code without the need for yield or await [2], with async functions having proper return types (i.e. not promise, but the type the promise would resolve to). Joel Wurtz has also put together a PoC of using Doctrine asynchronously using the fiber extension and Amp [3].
Febers/couroutines is one of the goals.
Another possible goal — event-loop primitives for internal extensions (e.g. async DB queries)
I think, we don't need async/await keywords or promises implementation in core
Anyway, as an expert in async PHP, you should tell us, what you really need from the PHP core...
I would be glad to hear your oppinion.
Thanks. Dmitry.
A new major may not be strictly necessary to introduce this feature, but it would ease introducing new keywords for awaiting IO and "promisifying" a function using fibers to allow simultaneous IO. These keywords could be async and await, though they would be used differently than JavaScript or other languages. See an example in the green-thread library [4], where the await() function uses Fiber::yield() to wait for promise resolution, and async() creates a promise from a function using await(). I would propose using keywords in place of these two functions.
I successfully am using Amp's http-server library with several other Amp libraries to run a website using long-running processes under PHP 7.2. I've seen no issues with memory leaks, crashing processes, or other unexpected behaviors. I think PHP is absolutely ready to shine in environments outside of per-request SAPIs. Core support for async is one of the few ingredients missing.
Aaron Piotrowski
[1] https://github.com/amphp/green-thread
[2] https://github.com/amphp/byte-stream/tree/ext-fiber
[3] https://github.com/joelwurtz/doctrine-async
[4] https://github.com/amphp/green-thread/blob/e13327a84be67d289aec87984f9d5c8e1fddd471/examples/simultaneous-async.php
Hey Dmitry,
hi Aaron,
- Better support long-running, async-based, microservices-focused execution model. It's probably no secret that one of the key reasons Node is gaining popularity is because it can handle a huge number of concurrent connections issuing relatively lightweight requests very efficiently - which is a good match for modern microservices based architectures. There are already several projects available for PHP that aim to provide similar functionality - most notably ReactPHP and more recently Swoole.
The main thing that is missing is that most of PHP's IO doesn't support async execution. What I think we should do is add as much support for async IO as possible across the various extensions and streams - so that using something like Swoole would become practical for more use cases. More specifically - the goal would be to provide extension authors with mechanisms that they can use to make their extensions/functions optionally asynchronous, without having to tackle the job entirely on their own. While we've done some research into this area, it requires a lot more research - but I'm cautiously optimistic that it can be done. We would potentially want to use libuv for this task, and potentially rewrite or otherwise refactor parts of the PHP streams system.Regarding async, are you referring to the Fiber extension? In my opinion, fibers would be the best approach for async in PHP. After using async/await in other languages, it doesn't offer a significant gain over what's already possible in PHP with generator-based coroutines in Amp. Using the fiber extension and a green-thread library that resumes fibers based on promise resolution [1], we've been able to write async code without the need for yield or await [2], with async functions having proper return types (i.e. not promise, but the type the promise would resolve to). Joel Wurtz has also put together a PoC of using Doctrine asynchronously using the fiber extension and Amp [3].
Febers/couroutines is one of the goals.
Another possible goal — event-loop primitives for internal extensions (e.g. async DB queries)
I think, we don't need async/await keywords or promises implementation in core
Anyway, as an expert in async PHP, you should tell us, what you really need from the PHP core...
I would be glad to hear your oppinion.Thanks. Dmitry.
Fibers are the major feature we're looking forward to, because it
allows async I/O in places that do not account for async, e.g. also
re-using interfaces designed for sync applications. Apart from that,
we want to avoid the boilerplate we currently have to write, i.e.
Amp\call wrapping a generator function.
We think that a methodless "Promise" / "Awaitable" type + fibers
implemented with keywords are the preferred way over the current Fiber
draft in the long run.
Fibers allow for transparent async I/O, which means we could maybe
transparently upgrade file_get_contents and others to use async I/O in
future versions, but something like that obviously needs an event-loop
in core.
That said, it's definitely something we want to push to PHP 8, but
nothing that has to be discussed in too much detail in this thread.
Regards, Niklas