Re: [RFC] Polling API Additions
| From: | Tim Düsterhus | Date: | Sun, 11 Oct 2026 11:29:28 +0000 |
| Subject: | Re: [RFC] Polling API Additions | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-132862@lists.php.net to get a copy of this message | ||
Hi
On 2026-09-30 19:57, Jakub Zelenka wrote:
I would like to introduce the Polling API Additions RFC: https://wiki.php.net/rfc/poll_api_additions This is follow up to Polling API RFC.Thank you for your RFC. As I already mentioned off-list I'm very much looking forward to the next parts of the polling API. I've given the RFC a full read now and have the following comments, many of which are questions intended to spark a discussion, instead of concrete fully-refined suggestions. 1. I agree with Ilia's suggestion to split the RFC into multiple scoped votes, even if everything is discussed at the same time for the “big picture”. The RFC itself already mentions “Every addition is useful on its own” in the introduction. This also allows to easily split off the parts that might need just a little more discussion. The “URI followup” for PHP 8.6 would be a good example. It started with 6 things, two were split off and the remaining 4 had a separate (primary) vote each. 2. Is the separate
WeakHandle interface and classes necessary? Would it also be possible to do something like `new StreamPollHandle(WeakReference::create($stream))`? It would be unfortunate if it would be necessary to duplicate everything as “strong” and “weak”.
3. Can the RFC document the expected callable signature for Context::onWatcherRemoved() (e.g. is the callback : void, what parameters are passed to it?).
4. I'm not sure about the naming and namespacing of the TimerHandle. Putting it straight into Io\Poll would make the namespace very full. For Random\Engine and the currently discussed Time\Clock we put the implementations of the interface in a sub-namespace named after the interface (and dropped the Handle suffix). In contrast to StreamPollHandle, the Handle suffix on TimerHandle doesn't carry any additional meaning and I don't think it helps disambiguation when imported in an unqualified way. Not sure if Io\Poll\Handle\Timer is the correct choice. Perhaps it can also be just Io\Timer when the Timer is usable standalone, e.g. using a Io\Timer::sleep() method or similar - or it would be correctly placed in Time\ similarly to Golang.
Even though I'm not 100% convinced by my suggestion, I wanted to put it out to allow discussing it. Perhaps someone else on this list has a good suggestion or reasoning based on my rough idea.
5. The RFC should explain if getTimeout() returns the constructor parameter directly - or if it returns the remaining timeout.
6. Would having a TimerHandle::pause() or TimerHandle::stop() or TimerHandle::reset() method be useful to allow modifying the timer without going through the Context?
7. As an aside: I'm happy that we could immediately find another use for Duration with the TimerHandle. This is a good indication for me that it was worth it getting it into 8.6 last minute to ensure a nice and consistent polling API :-)
8. For TimerHandle: Should the configured timeout and the periodic flag be exposed as (readonly) properties instead of methods? Those are effectively “properties” of the object in the English sense of the word.
9. Similarly to TimerHandle also for the SignalHandle: Would it theoretically be possible for the SignalHandle to act both as a standalone API and be usable with the polling API? Not sure if that makes sense. Is there perhaps precedent in other programming languages?
10. For ProcessHandle I don't think we should have both a regular constructor and named constructor. This makes discoverability worse, because the regular constructor doesn't show up in autocompletion for ProcessHandle::from*.
11. It is not unlikely that we want to introduce a new “Process” API to improve developer experience. Tying the ProcessHandle class to the existing proc_open() resources would be unfortunate when a new API with new concepts is then introduced. It will also not show up when autocompleting proc_*(). My suggestion would therefore be a proc_get_poll_handle() function ot similar that constructs the ProcessHandle, while keeping the integration contained in the `proc_*()' API.
12. For the NotifyHandle: Is it possible or does it make sense for it to support providing additional “metadata” as part of the notification, such as ->notify("hey, wake up"), similarly to how the ProcessHandle provides the exit status.
13. The “RFC Impact” section is following an old template, and the ecosystem impact subsection is missing. Could you add some short note about the expected Impact for e.g. ReactPHP?
14. In the “RFC Impact” section the RFC says “SignalHandle is limited to the CLI SAPI in thread-safe builds”, which is ambiguous to me. Is this “SignalHandle only works in ZTS CLI. It does not work in NTS at all and does not work in ZTS FPM / FrankenPHP” or is this “SignalHandle works in all NTS. For ZTS only CLI is supported”? Based on the explanation of the SignalHandle, I assume it's the latter?
15. Seeing the examples: Can you clarify the behavior of SignalHandle::getDelivered(). Which previous call is meant? Is it the previous call to SignalHandle::getDelivered() or is it the previous call to Context::wait()? Would it make sense to make SignalHandle::getDelivered() return a generator instead to make it more explicit that the return value is only meant to be consumed once?
Best regards
Tim Düsterhus