Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:130269 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 3B6941A00BC for ; Sun, 8 Mar 2026 11:27:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1772969271; bh=/OQMxD0Y6JojbO5vZ4kqWq5OT+0QfSe+w6mXaEcYPow=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=O0+fxMw2Ez8lsNDVyO99H9YNirERVHw3pFvEiXrovYJ1k5zeGKwwyw0ruU7LfkSJu NcvSs9mlq0xdo8n+dYpINEJCnXevTu7F6eaGcPYB26bdfOkr4ASnMmnMrX5XLv13i1 9NUM1M6C4Jn0iBKEA6gk6lXio3BUNNK//RhBrG1yht7ub8tPFxgEdTmkvUi62U6/y9 zt8mTCs/3r2gIqBAyLl0e8H0s8wCzs0TblcILh/gB9tvsZP1foan5zSA3cJrtT+tmd 2pJW/IcjbnuCC1NbwA7HQFzyIkZZjocyB/hdWAbeOifQSvHaAsQFw6Q+vK9my8PK5O TZ5LPPoJ4WQEg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id E1034180061 for ; Sun, 8 Mar 2026 11:27:50 +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=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from chrono.xqk7.com (chrono.xqk7.com [176.9.45.72]) (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 ; Sun, 8 Mar 2026 11:27:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bastelstu.be; s=mail20171119; t=1772969253; bh=iY/qBCcItOMQmTkpZXhfyZxODX3BZzNFOoT1MEvnwp8=; h=MIME-Version:Date:From:To:Cc:Subject:In-Reply-To:References: Message-ID:Content-Type:from:to:cc:subject:message-id; b=PJ8DVaTpop/yyoDVlGxls80XBU7YesHh7frhvYtGVWnjG2zCotahRs5/T7zFtuxGO 4GUDbf7LRm8Fz7rBC0anOjLG7yQcCJ45oP578hMPwfiau1i8oNkQbUucVp36+aN5tq nR3HlMI+3RvrpGtHAT8o2paEwlTbJjGkuEI7Q06k7FfcgL5wF3CL+CuuWa5oWZQ/nH SCriIKHCxmDLlH5ZdA0tcOLxg1tK6fgbY9EIrhKBZgWH8YoRL+E5LtBpORbJLF7OrJ SL0Q5CxkdkuiRzd/YmFHOYHIV5+CGqStFLhcjNVK3TQvIIIodKCOjGyCMIPOiwBpAU ZeCAvcTdVHrBw== Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 Date: Sun, 08 Mar 2026 12:27:33 +0100 To: Jakub Zelenka Cc: PHP internals list Subject: Re: [PHP-DEV] [RFC] Polling API In-Reply-To: References: <926a26a6-eb89-49aa-a387-6cc79caa29c1@bastelstu.be> Message-ID: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit From: tim@bastelstu.be (=?UTF-8?Q?Tim_D=C3=BCsterhus?=) Hi Am 2026-02-22 17:16, schrieb Jakub Zelenka: > Thanks for the feedback! Thank you. I've given the RFC another read now and have some minor things to remark: 1. I don't think it makes sense for the majority of the classes to be serialized, because they rely on “in-process” state, specifically file descriptors. This includes Context, Watcher, and the handles. Serializing the enum and Exceptions by themselves is fine. The RFC should note that serialization is prevented and the implementation adjusted. 2. Similarly for any new classes, I recommend to always set `@strict-properties` to prevent shenanigans with folks accidentally adding dynamic properties to these classes. This should be done for everything, including the exceptions. 3. I have a question as someone who never used Fibers in production: Is it necessary or helpful for the API to provide some “convenience” functionality related to Fibers (e.g. automatically suspending or unsuspending Fibers)? I'm asking now, because adding that functionality later might be a breaking change in behavior. If it's not necessary or can be added in a backwards compatible way, that's fine, of course. > On Sun, Jan 18, 2026 at 1:24 PM Tim Düsterhus wrote: >> - Context::wait() takes a millisecond timeout. This feels >> insufficiently >> granular. I am wondering if we should rather use either micro (as >> returned by microtime) or nanoseconds (as returned by hrtime) - or >> possible an instance of DateInterval (which would use microsecond >> resolution). >> > > Yeah this makes sense. I used the same convention that is used in > streams > which means two params so it is changed to: > > public function wait(int $timeoutSeconds = -1, int $timeoutMicroseconds > = > 0, int $maxEvents = -1): array {} I feel that using two parameters is providing for a very clunky API, which is also acknowledged by the doc comment on $timeoutMicroseconds "Only used when $timeoutSeconds >= 0". I would have suggested DateInterval again, but I'm just seeing that it seems there is no documented way to manually construct a DateInterval with microseconds. Perhaps the following suggestion would be a good middleground: - Change $timeoutSeconds to int|null: If null is specified, the timeout is infinite. - Throw ValueError if $timeoutSeconds < 0 - Throw ValueError if $timeoutMicroseconds < 0 - Throw ValueError if $timeoutSeconds === null && timeoutMicroseconds > 0 `null` is a much more natural value for “no timeout” and by throwing ValueError we make sure that we don't have a situation where a parameter is silently ignored. Similarly for `$maxEvents` it might make sense to use `null` for “use a default value”? Also: What happens if I specify `$maxEvents = 0`? Is this useful? > >> - For Handle I am wondering about abstract class vs interface. Since >> the >> Handle presumably doesn't have any non-abstract methods, an interface >> feels more correct / more flexible. >> > > I have been considering this already and there are reasons why I prefer > abstract method here. > > The abstract method is better for internal implementation and limit > overhead of PHP calls that would be required for interface. The > advantage > is that I can use internal struct API through C operations which allows > bypasing the call and can do optimization for some backends - e.g. > timeouts > for kqueue don't need file descriptor. You can bypass the “VM method” for interfaces and abstract methods alike. A good example would be ext/random which allows changing the engines by the Random\Engine interface, but for engines implemented in C, the Randomizer doesn't go through the userland API, but instead calls the engines directly. > I also think that there is not really much use case for user space to > implement their own handles so such interface would be used only > internally > anyway. This applies equally to interfaces and abstract methods. The abstract base class however will make it much weirder when a specific (future) handle might need to implement additional interfaces or abstract classes. > In addition interface would effectively expose the internal stream fd > which > is currently hidden and makes harder messing up with stream fd which > might > cause various issues. I don't understand that point. For both an interface and an abstract method, the method would exist on the child class and thus can be called by a developer. >> - For Handle: What happens if I extend this class in userland and >> attach >> it to a Context. Will things break? What if I return the number of a >> non-existent FD? >> > > Depending on backend it will result either in FailedHandleAddException > (epoll, kqueue, possible event ports as well) or on Windows it would > likely > fail during wait with FailedPollWaitException. So it can be handled by > catching FailedPollOperationException. This is however very unlikely > edge > case so I don't think there is much point to worry about consistency. > As I > said the use case for implementing custom Handle is a bit moot. Okay, I just wanted to make sure that nothing *bad* happens. If it safely errors, this is fine. Best regards Tim Düsterhus