Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129023 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id ED57E1A00BC for ; Fri, 31 Oct 2025 12:06:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1761912420; bh=oNfnNAtL5n1Wonjqyt7x2h45XIefrQsklfQNgtfhDqE=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=jZvrSDcpl7V0bHQ6IX+rnGvqqJq9zh0P/SEtT1LcZqlZjmdxQ/8PiAXXjDu+pUPLo Jt5psl5OCqAet52ObgJnafYY5qFwxgOuhdO9F4P9XBxtfUpJW+qbLAWY+5YZUFPR+B 4+P/d9yd33dUOwMkfDwlKQgdOC6oYIs8o5dIpHuLODwgCidz6+1SKR/u3yjuHLa7mu JKe2B55SBtRnyNKhlCfVJMeQ9OxRUO7yzZe1GDbwDEwNgxfYUwMVciDwvTwHfWaeBu mycuct0o2fNPtVZdTq7yRuiWg7amk+PE57SJkhd7VTzJv8SSY6d+a4OAwaF4ydzhaT 2d0DtuEs6KYhg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 077AC1801E8 for ; Fri, 31 Oct 2025 12:06:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=1.0 required=5.0 tests=BAYES_40,DMARC_NONE, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-oi1-f176.google.com (mail-oi1-f176.google.com [209.85.167.176]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Fri, 31 Oct 2025 12:06:53 +0000 (UTC) Received: by mail-oi1-f176.google.com with SMTP id 5614622812f47-443a7490a54so1149461b6e.1 for ; Fri, 31 Oct 2025 05:06:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761912408; x=1762517208; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=pJiNdHASWx0Up0pU1dRj2maNGB4vZJS4hwrGLmXqaJY=; b=RugRr4NP5Wal/Pp6ajtJLfQ4B5sJMDnG28PbjTLZjwZSpxxO3OstLvSm8f7KVWuooC G0XfhpDwiPwgMsC9daiI4tbNVkkJS0afeft1vnPXoz6FMwQnLZq1V7+dX3Rtjs0xGfUp itKKFs2Q7WXwVEHgbcioPIwAE/6erM9aWVaaNZxitBab8cP/qRgBanF1pvq8uJY8oS7U jxztpAlV8qGj+1tafBHAUvCVhrar/LzfLgVsV0fQtT7CC/BIbGffNhh+6iA8NEV8+zQ7 bUPBsOqoWN1kihGnS5ooUCU8zBCFQ4kNwxScGv/z7FLG5RqVo9JO7g/TD6/gEVN8eaMC vRXg== X-Gm-Message-State: AOJu0Yx0igSvLsRpmEiXu63/Y/NonSdivzuDS6Qb887Px73Sslq4q/eH DiIRPoLg3Mh7NKIOYZ2EKkGsQlYMZRdsBwE7bpHmQfTw3qdt3MyRgErqeWkQ70wXDTNlpov1OKm /UFWL+8sGsIGjmKA5OYodK59m28HQxIjvkTVN X-Gm-Gg: ASbGnctJeI5Jkr+BZLoLXCvHotquXrpOLbSfTcB9k8SyaUuOh7ncrz/4PjTWGdZuFpn xOJfiqqCu0Q1kHOvovwj9f+xmIdUUodLmP2/D2iMIHU8m77oEami8nFmhWM2SsGVwtQYgtRLuAy 2oTOIbwRLZfnmUC3RdsCOqRm3LSqqUJt48GDe4RxwozdY2H3KpGC5LzlYraoyOVtnO63uPX+IK+ ywbtUSwwOBOzZfW6awL/KA4m5Z9TydxWHcr491JsqXqT2asj0Q2D9gFy90= X-Google-Smtp-Source: AGHT+IGswcDHn7nUIoaDW2tmY3QJcZBFy2VOMf+Kbx+zOEK3kmiMvShk9rofPg7ZluaASD4UAbj/cutziqwi/S+q0Hk= X-Received: by 2002:a05:6808:3996:b0:44d:b300:e903 with SMTP id 5614622812f47-44f9606d48amr1263171b6e.54.1761912407668; Fri, 31 Oct 2025 05:06:47 -0700 (PDT) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: In-Reply-To: Date: Fri, 31 Oct 2025 13:06:36 +0100 X-Gm-Features: AWmQ_bmS2-2bYghrAEgXxUoy4d8J-PGOze9v-IOfr32ijRflk03WPS8iVnfVmzQ Message-ID: Subject: Re: [PHP-DEV] [RFC] Polling API To: =?UTF-8?Q?Tim_D=C3=BCsterhus?= Cc: PHP internals list Content-Type: multipart/alternative; boundary="0000000000002f3deb064273334d" From: bukka@php.net (Jakub Zelenka) --0000000000002f3deb064273334d Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi, On Fri, Oct 31, 2025 at 10:40=E2=80=AFAM Tim D=C3=BCsterhus wrote: > Hi > > Am 2025-10-30 22:06, schrieb Jakub Zelenka: > > I would like to introduce a new polling API RFC that is part of my > > stream > > evolution work: > > > > https://wiki.php.net/rfc/poll_api > > 1. > > Thank you for the RFC. I've taken a first skim of the proposal and it > immediately raised the question of naming and namespacing in particular. > Our naming policy at > https://github.com/php/policies/blob/main/coding-standards-and-naming.rst= #bundled-ewill > be alwaysxtensions > > says that =E2=80=9Cnamespaces SHOULD be used=E2=80=9D and given that this= is a > completely new API, I think we should namespace them. > > My understanding is that the proposed API relies on a file descriptor > and not something like a timeout. It therefore makes sense to me to put > it into a `namespace Io\Poll;` or similar. We would then also have: > > namespace Io; > class IoException extends \Exception {} > namespace Io\Poll; > class PollException extends \Io\IoException {} > > I thought about this and think this might be a good idea. Just to note internally it might not always be a fd. For example, TimerHandle might implement internal API not requiring fd because some platforms (e.g. kqueue ones) don't use it but from the API design (and on Linux), it is fd based so putting that to Io namespace might make sense. The thing is that I also started working on new IO copy API: https://github.com/php/php-src/compare/master...bukka:php-src:io_copy . This is just a stub but it aims to introduce new IO layer (initial mainly for copying but potentially cover more operations) and it should also contain a new IO ring (on Linux based on io_uring) variant that could be potentially also exposed in some form. I will get it to some working form in the coming weeks and then thing how to organise it with the poll. > The StreamPollHandle method should possibly be placed in the global > namespace still, since the stream functions are sitting there - and a > SocketPollHandle would of course be sitting in the namespace of the > Sockets extension. > Yeah those could stay in global and just extend Io\Poll\Handle. > 2. As for the PollBackend enum. > > Is there a reason why this is a backed enum? Generally speaking enums > should not be backed, unless there is a good reason for this. I don't > think there is in this case - and none of the native enums are backed so > far. > > I missed that they should not be backed. I just saw `enum AdjacentPosition : string` in Dom so thought that it's fine to use it... Will change it. > 3. Exception-wise. > > StreamPollHandle::__construct(): This should probably be a ValueError, > not a PollException, since passing an invalid stream is a programmer > error. > This makes sense. > > In the other cases it probably makes sense to further split the > PollException into purpose-built exceptions according to the Throwable > policy at > > https://github.com/php/policies/blob/main/coding-standards-and-naming.rst= #throwables > (=E2=80=9CThe exception message MUST NOT be the only means of distinguish= ing > exception causes that the user might want to handle differently.=E2=80=9D= ). > > This makes sense and I will introduce more exceptions. I will not use exception per errno but some middle ground is a good idea. Maybe per op exception with codes representing specific errors would be make sense? > As an example PollContext::__construct() should probably throw a > BackendUnavailableException or something like this. For > PollContext::add() I'm wondering in which cases a handle =E2=80=9Ccannot = be > added=E2=80=9D. It fails if the same fd is added. This is also limitation of backends (e.g. epoll does not allow the same fd to be added twice). I got error code for the specific errors so this should be probably exposed as well. It would still make sense to differentiate that it's an exception for addition. > Is this an error situation that users will encounter in the real > world? Similarly, when can PollContext::wait() fail? > Wait might also fail but less likely. > > 4. PollBackend > > Is the availability of the backends known at compile time of PHP or at > runtime only? Depending on that it might make sense to only > conditionally define the enum cases, allowing users to check > availability with `defined()` or checking the output of `::cases()`. > Alternatively, a `public static function getAvailableBackends(): array` > could be added. > > It's compile time but not sure if I like exposing enum only if compiled in as it makes the checks harder. This part is not really something that users should use but it's really more for testing purpose. In reality everyone should just use default Auto... But getAvailableBackends() might make sense even for testing. Maybe it could also have per enum method isAvailable() so user can check that but not sure if it's needed. Kind regards, Jakub --0000000000002f3deb064273334d Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

On Fri, Oct= 31, 2025 at 10:40=E2=80=AFAM Tim D=C3=BCsterhus <tim@bastelstu.be> wrote:
Hi

Am 2025-10-30 22:06, schrieb Jakub Zelenka:
> I would like to introduce a new polling API RFC that is part of my > stream
> evolution work:
>
> https://wiki.php.net/rfc/poll_api

1.

Thank you for the RFC. I've taken a first skim of the proposal and it <= br> immediately raised the question of naming and namespacing in particular. Our naming policy at
https://= github.com/php/policies/blob/main/coding-standards-and-naming.rst#bundled-e= will be alwaysxtensions
says that =E2=80=9Cnamespaces SHOULD be used=E2=80=9D and given that this i= s a
completely new API, I think we should namespace them.

My understanding is that the proposed API relies on a file descriptor
and not something like a timeout. It therefore makes sense to me to put it into a `namespace Io\Poll;` or similar. We would then also have:

=C2=A0 =C2=A0 =C2=A0namespace Io;
=C2=A0 =C2=A0 =C2=A0class IoException extends \Exception {}
=C2=A0 =C2=A0 =C2=A0namespace Io\Poll;
=C2=A0 =C2=A0 =C2=A0class PollException extends \Io\IoException {}


I thought about this and think this mi= ght be a good idea.

Just to note internally it mig= ht not always be a fd. For example, TimerHandle might implement internal AP= I not requiring fd because some platforms (e.g. kqueue ones) don't use = it but from the API design (and on Linux), it is fd based so putting that t= o Io namespace might make sense.

The thing is that= I also started working on new IO copy API:=C2=A0https://github.com/= php/php-src/compare/master...bukka:php-src:io_copy . This is just a stu= b but it aims to introduce new IO layer (initial mainly for copying but pot= entially cover more operations) and it should also contain a new IO ring (o= n Linux based on io_uring) variant that could be potentially also exposed i= n some form. I will get it to some working form in the coming weeks and the= n thing how to organise it with the poll.
=C2=A0
The StreamPollHandle method should possibly be placed in the global
namespace still, since the stream functions are sitting there - and a
SocketPollHandle would of course be sitting in the namespace of the
Sockets extension.

Yeah those could sta= y in global and just extend Io\Poll\Handle.
=C2=A0
2. As for the PollBackend enum.

Is there a reason why this is a backed enum? Generally speaking enums
should not be backed, unless there is a good reason for this. I don't <= br> think there is in this case - and none of the native enums are backed so far.


I missed that they should not be backe= d. I just saw `enum AdjacentPosition : string` in Dom so thought that it= 9;s fine to use it... Will change it.
=C2=A0
3. Exception-wise.

StreamPollHandle::__construct(): This should probably be a ValueError,
not a PollException, since passing an invalid stream is a programmer
error.

This makes sense.
=C2= =A0

In the other cases it probably makes sense to further split the
PollException into purpose-built exceptions according to the Throwable
policy at
https://github.c= om/php/policies/blob/main/coding-standards-and-naming.rst#throwables (=E2=80=9CThe exception message MUST NOT be the only means of distinguishin= g
exception causes that the user might want to handle differently.=E2=80=9D).=


This makes sense and I will introduce = more exceptions. I will not use exception per errno but some middle ground = is a good idea. Maybe per op exception with codes representing specific err= ors would be make sense?
=C2=A0
As an example PollContext::__construct() should probably throw a
BackendUnavailableException or something like this. For
PollContext::add() I'm wondering in which cases a handle =E2=80=9Ccanno= t be
added=E2=80=9D.

It fails if the same fd is = added. This is also limitation of backends (e.g. epoll does not allow the s= ame fd to be added twice). I got error code for the specific errors so this= should be probably exposed as well. It would still make sense to different= iate that it's an exception for addition.
=C2=A0
Is this an error situation that= users will encounter in the real
world? Similarly, when can PollContext::wait() fail?
<= br>
Wait might also fail but less likely.
=C2=A0
<= blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l= eft:1px solid rgb(204,204,204);padding-left:1ex">
4. PollBackend

Is the availability of the backends known at compile time of PHP or at
runtime only? Depending on that it might make sense to only
conditionally define the enum cases, allowing users to check
availability with `defined()` or checking the output of `::cases()`.
Alternatively, a `public static function getAvailableBackends(): array` could be added.


It's compile ti= me but not sure if I like exposing enum only if compiled in as it makes the= checks harder.=C2=A0 This part is not really something that users should u= se but it's really more for testing purpose. In reality everyone should= just use default Auto... But=C2=A0getAvailableBackends() might make sense = even for testing. Maybe it could also have per enum method isAvailable() so= user can check that but not sure if it's needed.

<= div>Kind regards,

Jakub
--0000000000002f3deb064273334d--