Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129924 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 10E5B1A00BC for ; Sun, 25 Jan 2026 21:21:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1769376088; bh=V0spNAEX6B8ilwqw5qr6zOjLG2m+GQ5N2kDeWvto/l8=; h=Date:From:To:In-Reply-To:References:Subject:From; b=OuNfsip7vkIopWIRi/KSxWcbpwiTLyvCtbrLL+AZ6uj5FLERYXVDZNJpEbmmeDFIE uGSof1+XcWrKDEAqPWNW4nYwsCM4af/ZUVBsEpSvn4hdiG07QxPFMMmbiUQmXZm5TJ BFvOC/JygEgP/oShx4T7eAyVX+h4Moa0jmrnln3uILKQkr+4II0s1O6d1nSiLOPCvn fW86AwMAiraNOyvvoB//68+melMRmt0ENAIaKiaQlVe5oZNzAzSs8s8DhYre7TPc8A E6ut7JtNkMY0o5q8CQ2KCtvDZoPHXh/d6ZIwW5qAi0l7kUqluWpSazcx+8Q8EcJ8Q4 KPqa+3htJTfNw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id A8E501804BE for ; Sun, 25 Jan 2026 21:21:27 +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.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,RCVD_IN_DNSWL_LOW, SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from fhigh-b2-smtp.messagingengine.com (fhigh-b2-smtp.messagingengine.com [202.12.124.153]) (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, 25 Jan 2026 21:21:17 +0000 (UTC) Received: from phl-compute-04.internal (phl-compute-04.internal [10.202.2.44]) by mailfhigh.stl.internal (Postfix) with ESMTP id E60807A00C4 for ; Sun, 25 Jan 2026 16:21:11 -0500 (EST) Received: from phl-imap-02 ([10.202.2.81]) by phl-compute-04.internal (MEProxy); Sun, 25 Jan 2026 16:21:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to; s=fm2; t=1769376071; x=1769462471; bh=SHVejedaqDibZuIQPEMFL WoAoCebHcTlph0g4uFaR+o=; b=fZe2KcY5o6bjMEIIau2R1zwTQ5fqLYas2JFQ1 jGzdUTjyRV+7cRnIa7QwCVqRsSmYGfn857M9DAfR4/KJv4i7kX4l8ymTA3SxfRnA Ft3LYrzhVkQEnmCSkDzrLMUGRNera5WrEAt/fFvKMUOEuIYPc7UBKER3fQF3X1k9 kO38aiHk0fbhCfFuLPSp2+5sBg8ayTbRYIi0sqx2A4BjiX2o6Z7hf05axvIOHJLw uzqkoYk3n/4NTlm6bn8EF6Opycnsgea0F33g0lG30NWD5Ipq7sUMPnVdaaduzdTY Fy7Mzo/avtPSP+yjr6Lod9jlTdqqJslofxgmXYpG041i6+yIA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm2; t=1769376071; x=1769462471; bh=S HVejedaqDibZuIQPEMFLWoAoCebHcTlph0g4uFaR+o=; b=NeiNPqw/R4JhM83D1 2rthhR3lCPBZH6/CRc+TU6GiimdVQjwpijxs+gpUapivAi94c4tB03SY43bQqFgl fQsX24Jf1ekzvLm9i7lZULSD96fqaO+RTlTqTeo4h5+cgnQgcz8wRNuqNYuMZyNY KUdpaQVb4Lu2V4zt+BMi7V89w3tGvaG+cEoU3AONt0ytcpLynWJE7ETW3lo2m7Nn Qx+zlgWvunRDz6C68rPTX/UldGogfnX6m/leQGoW4GtwezfUtC9RrLF74kL6yR7F CBXN2uXIZ8zCtSZy1AkzYxKfCyqw3FyNaE9y2dHD8Z8m7B7C5wE8pjzYlDlzbF5E 8C5wA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgdduheehkeeiucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepofggfffhvffkjghfufgtgfesthejredtredttdenucfhrhhomhepfdfnrghrrhih ucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhmqe enucggtffrrghtthgvrhhnpeeuvedvudfhffffhfelueehvdejvefgleegteegffetudef leehgeefvdehgeelteenucffohhmrghinhepphhhphdrnhgvthenucevlhhushhtvghruf hiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehlrghrrhihsehgrghrfhhivghl ughtvggthhdrtghomhdpnhgspghrtghpthhtohepuddpmhhouggvpehsmhhtphhouhhtpd hrtghpthhtohepihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 65CFF700065; Sun, 25 Jan 2026 16:21:11 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: A1mztAC4zmZ3 Date: Sun, 25 Jan 2026 15:20:16 -0600 To: "php internals" Message-ID: <4a42e150-44af-4240-9854-2d47d067d760@app.fastmail.com> In-Reply-To: References: Subject: Re: [PHP-DEV] [RFC] True Async RFC 1.7 Content-Type: text/plain Content-Transfer-Encoding: 7bit From: larry@garfieldtech.com ("Larry Garfield") On Thu, Dec 25, 2025, at 1:57 AM, Edmond Dantes wrote: > Hello everyone! > > RFC https://wiki.php.net/rfc/true_async > > Here is the seventh version of the RFC, revised and expanded. Notes, collected as i go: - Most RFCs have an example in the introduction of what the proposed syntax looks like in a small but meaningful example. Please include such, as it helps "set the stage" and provide context for the rest of the RFC. - Please break up the API Overview code block into several pieces by type to make scrolling easier. - As I've said before, I'd rather have keywords than functions for the main API. - Please please do NOT have finally() be a function on its own. current_coroutine()->finally() is sufficient. Having it on its own is going to be too confusing with the finally keyword for exceptions. Can we find a better name for it that isn't confusing with exceptions? onCompletion()? What is the difference then between $coroutine->finally() and register_shutdown_function(), when the current coroutine happens to be main? - getSpawnFileAndLine() and getSpawnLocation() - It's non-obvious when they're first mentioned what the difference is. I don't know if they're described better further down, but they should have a docblock here to avoid confusion. - getAwaitingInfo(): array - Hell no, no struct arrays. Make it a class. - Remember, we now have PFA, so `spawn('sleep', 2)` can now be spelled `spawn(sleep(2, ...))`, to make it available for IDE analysis. :-) (I'm not sure what the implications of that are/should be for all the other "callable and arg array" cases.) But at very least, please use `func_name(...)`, not a string, in all examples. Function name strings should basically never be used again. (Another argument in favor of keywords.) - "The non-blocking version of the file_get_contents function is not part of this RFC." - Wait, I'm confused. I though the entire point of this RFC was that we don't need a user-exposed alternate version of file_get_contents(). It just blocks or doesn't as needed. Now you're saying that's not the case? We need to use the silly spawn() syntax or it will block our coroutine? That's a no-go for any existing library that happens to have a file_get_contents() in it, which would then block if it gets called inside a coroutine it doesn't expect. If that's not the case, then this comment is highly misleading. Either way, it's scary. - "This means that multiple calls to select may produce different results. " - I don't believe a select keyword or function has been discussed to this point, so this line is confusing. - Completable interface section needs an example. I don't grok what it means in practice. I also don't understand what Awaitable is for other than being a parent of Completable. At least not yet by this point in the RFC. - The examples seem very inconsistent. Some are using foo(...), some are using strings, and the "await with cancellation" example is using a long-closure syntax for reasons I do not fathom. The inconsistency is making it difficult to get a sense for what typical usage will be like. - "As soon as the $cancellation is triggered, execution is interrupted with an exception " - What does triggered mean? When it starts? Ends? Something else? What's a use case here other than sleep? This is all very unclear. - In Fibers, in the basic example, "start() blocks until the fiber completes" - I assume that means it blocks the calling coroutine? Or does it block the whole system until it completes? - I have no idea what it means for coroutines to be "symmetric". This is stated as a thing, but I have no clue what that means. That makes much of the Fibers section incomprehensible. - I will have to defer to the existing async gurus (especially Aaron P of AmPHP, who wrote the Fibers RFC) to determine if the FIber integration is logical and reasonable. For me, it feels very complicated but that may be necessary. I am not sure. - "Active coroutines (running or suspended) are protected from collection while they have pending operations" - If I'm reading that correctly, it means `span(very_long_function(...))` will start a coroutine, but not assign it to a variable. So I cannot track it or refer to it, but it will still run in the background until it completes, at which point it will get GCed. Is that correct? - The FrankenPHP example linked to... doesn't seem to do anything to start a coroutine. I don't know what it's supposed to be demonstrating other than FrankenPHP itself. - OK, now all the way at the bottom we get to an explanation of getSpawnFileAndLine() vs getSpawnLocation(). I am not convinced we need both, and the naming is highly confusing. More discussion to have here. - Non-Async code can use Cancellation, but... what does that even mean or do? Why would someone use it? This is sneaking in a 3rd error type without much guidance. catch(Throwable) is surprisingly common (rightly or wrongly), so this feels like a major pothole potential. - Oh crap, Scopes are now a SEPARATE RFC, of similar length? See previous "this thing is huge" comment... I do not have the bandwidth right now to review that, but I feel like I have to in order to speak to this one intelligently. I also haven't gotten to read any of the linked references, as I have run out of time. More general comments: This seems mostly logical as a low-level API. As I have stated before, though, I don't want a low-level API. I want a *safe* API. I am not convinced those are compatible. And I certainly do not want to see the low-level API in one release and then have to wait for the next release for the safer API. Having pipes and PFA in separate releases is bad enough. :-) That this allows for zombie coroutines or "lost" background coroutines to exist is, to me, a major problem. I realize changing that means bringing scopes back in, which makes it bigger, but... I don't want to hand footguns to a million PHP developers with no async experience. I don't trust us with that kind of power to not do something grossly stupid. As I've said before, I don't like await, spawn, etc. being free-standing functions rather than keywords. That is very limiting on the syntax they can use. It also means, as the examples show, we get this pattern very often: await(spawn($fn)); That's very clumsy. It introduces two layers of wrapped functions, which means a lot of extra parentheses. I... have no idea what would happen if one used pipes here, but that's also an open question. I think it would be: $result = $fn |> spawn(...) |> await(...); I am not sure if I like that or not. But regardless, the "start coroutine and block until it's done" operation is common enough that it needs a cleaner way of writing it than two nested function calls. We can debate what exactly that is, but we need it. I would much rather have $cor->onComplete() than finally(). And absolutely no global function by that name, which is way too easy to confuse with the existing keyword. All the use of inline function callbacks also, once again, demonstrates why our current long-closure syntax is a problem. We need to fix that, for simple ergonomics if nothing else. It makes this sort of code a pain in the ass. --Larry Garfield