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