Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129274 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 2881F1A00BC for ; Sun, 16 Nov 2025 20:10:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1763323815; bh=j7aq1kA9L8GCpR7ob2UC55+IdQn/JikMd+aWevio0cA=; h=Date:From:To:In-Reply-To:References:Subject:From; b=Ipono9QjRelaIqU17Hxos2TFjnT4MgW+izzkOGzVYsVFI1M4+whdPQlMJYJsAl63m ObdC68OitkgjDjBHuxzXZF1QGZxZFuaIx+jAgyQqLNLIj0mykbRAFYmMPZHJJpQ/rW eakC1gKOcD5qtivQne/U2xjE9Sd05cDkhdvEl1lv18XHpHX3YtJDvjIEUsT5JYMJEz gRc2IQ5grXrl854u0m/VVhxTKTM9TTMP8sGx/uOTViN11KOMaKMAPaqrswwtbQJIn8 pFj1impQAQTy4ik+To2xpwqvyzYBRHACHwApsS9+S/xH4gwQQNJDnb6xZz6iJmPi7D s00HospmZd8RQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 81A79180050 for ; Sun, 16 Nov 2025 20:10:14 +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-a2-smtp.messagingengine.com (fhigh-a2-smtp.messagingengine.com [103.168.172.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, 16 Nov 2025 20:10:14 +0000 (UTC) Received: from phl-compute-04.internal (phl-compute-04.internal [10.202.2.44]) by mailfhigh.phl.internal (Postfix) with ESMTP id B4A9514000D3 for ; Sun, 16 Nov 2025 15:10:08 -0500 (EST) Received: from phl-imap-02 ([10.202.2.81]) by phl-compute-04.internal (MEProxy); Sun, 16 Nov 2025 15:10:08 -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=fm3; t=1763323808; x=1763410208; bh=AhZl2oynX/wr8Hi7RkTmu TZ47WiLzWks5qNu44D3cPs=; b=Gi1oboBjYjwRIEWzHZFdav9DN837E+B1gFHns QE3wcrSj0MAVXFnRGTVdhkBkfSkjvGj7qFm6f5f9cTSZbpgwhpENfMlT1Rw3biQK lpx/qJeGTIyfdmjeUjUbXIbCWFjWyXoWXUyHPhHPKbweMjdRxa6gSIlO2sFlqoXA FiG5SxgUq2FFsTKBZM+IQx+7LmWQBP8O+fw6NhGnfVRXZokqdbL8vjmfnDRgjLKj 1Bv3L3lej7EqccOI/nIFmJwzMg7vPBUaXahS6iZOqzehYn6/tv0ihcVA/oSsQ+1S fw4bHSCEv65ZBoiXOFS//WnvurBbU5HnIH0eO7kH00sOj0onw== 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=fm3; t=1763323808; x=1763410208; bh=A hZl2oynX/wr8Hi7RkTmuTZ47WiLzWks5qNu44D3cPs=; b=Ex1QfTJHL3pzYz9GR w+v45Ns6etf8Lf/MV4IH1TjBBpLpefmhlzMdikMhEpCgWDzRDum0orbqbnpX8a0j bBPT8GiH+bgFK2N4edkxNZDEjMB0qZ2/5DvnzTSE6sbUyOLgy03FZ0zewBhc4Dh2 l2QPgcmgjzWIDFIZaXHMgA+iUJdESYdcweOHE2c14PMN15JcK0wfRnseRK402D3F QEGcTVe/z5fhPGcKNzbofXTj3mhauulSF/dQqc3O1K0zgJoq+ax2AZIEpdq/2g6/ uyU+rW5Y3C86oQBG0pLK4Ja+8NGKBYfVYqzECLSWyiimjsuAEmmpQuu5cY1fvxfq K2lpQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdeggddvudeiheduucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepofggfffhvffkjghfufgtgfesthhqredtredtjeenucfhrhhomhepfdfnrghrrhih ucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhmqe enucggtffrrghtthgvrhhnpeffieeivdfhvdeguddttdegteeiueegvefhteehfeeffeet udeitdehtdegjeeuieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrih hlfhhrohhmpehlrghrrhihsehgrghrfhhivghlughtvggthhdrtghomhdpnhgspghrtghp thhtohepuddpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtohepihhnthgvrhhnrghlsh eslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 6046C700054; Sun, 16 Nov 2025 15:10:08 -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: Ahf6UnkKtvxF Date: Sun, 16 Nov 2025 14:09:48 -0600 To: "php internals" Message-ID: In-Reply-To: <08303459-b4ab-44a8-9795-0fb7f82914d0@app.fastmail.com> References: <6618a91c-5393-4f40-88b5-b5041ee09deb@app.fastmail.com> <3e0cf0a1-c1a3-4e05-97ba-0eeb7f559a53@app.fastmail.com> <41c5eed0-dd1b-4ea4-99cf-f6d16682bd7f@app.fastmail.com> <08303459-b4ab-44a8-9795-0fb7f82914d0@app.fastmail.com> Subject: Re: [PHP-DEV] Re: PHP True Async RFC Stage 5 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable From: larry@garfieldtech.com ("Larry Garfield") On Sun, Nov 16, 2025, at 4:44 AM, Rob Landers wrote: > On Sat, Nov 15, 2025, at 23:06, Edmond Dantes wrote: >> > I guess my main thing is that this RFC should only cover coroutine = machinery: it should not promise "transparent async" or "code >>=20 >> It=E2=80=99s like trying to dig a hole with half a shovel :) >>=20 >> > that works exactly the same" OR if it wants to make those claims, i= t should actually demonstrate >> > how instead of hand-waving everything as an "implementation detail"= when none of those claims can actually be validated without those detai= ls. >>=20 >> All of my claims are backed by tests :) > > I will leave with some final advice. The problem with tests is that=20 > they only validate the current implementation, which isn=E2=80=99t gua= ranteed=20 > to be the final implementation. I would recommend reviewing your tests=20 > and matching up each of them to where you mention that behavior or=20 > define it in the RFC. If the tests are implementation-specific, then i= t=20 > needs to be defined in the RFC. For example, you say that the schedule= r=20 > is 100% an implementation detail, but your outputs in the tests rely o= n=20 > a specific ordered queue. You should at least define the ordering the=20 > queue should be processed in the RFC (LIFO vs FIFO) so that even if th= e=20 > implementation changes, the tests still pass. > > That=E2=80=99s one example, you can review my previous comments to dis= cover=20 > other examples, such as defining the rules of suspension points. > > I wish you the best, A few thoughts to add: First: People, please don't include me on the reply line. I just got 30= messages doubled. Once or twice, fine, but somewhere in that thread so= meone should have trimmed the To field back to just the list. Or use re= ply-list, just once. If nothing else, please remove *me* from the name = list. %3C/rant> Second: I think the key point here is one that Kevlin Henny has raised b= efore in presentations: If you have any sort of concurrency, shared muta= ble state is a problem. Shared immutable state is no problem. Unshared= mutable state is no problem. Unshared immutable state is no problem. = Shared mutable state is where the problem is, and if you eliminate that,= you eliminate virtually all race conditions. (See also: the entire des= ign of Rust). Naturally, easier said than done. While I presume the people who frequent this list are disproportionately= the sort that already try to avoid shared mutable state on principle (I= do), we are not a representative sample. So "the code runs exactly the= same, modulo any shared mutable state, there be dragons" (Edmond's poin= t) is true, but given the state of the PHP ecosystem also means "There's= therefore an unknown but probably very not-small number of dragons out = there, just waiting for us" (Rob and John's point, among others). "This hasn't been a problem in practice for Swoole", I will take at face= value as true (I have no data on the matter); the degree to which that = is indicative of the rest of the ecosystem is what is highly debatable; = Swoole et al represent a tiny fraction of the ecosystem, and is used by = people that know they're using it. Or they're using code written by top= -notch developers who have been preparing for this sort of scenario for = a decade (Laminas, Symfony, etc.). The degree to which we can apply tha= t lack of concern to the billions of other lines of PHP code out there i= s an open question. So the debate seems to be between "let's assume it's safe and make the n= icer-to-work-with option" and "let's assume it's unsafe and so we need a= nother option." But Javascript-style colored functions would suck, for = well-documented reasons. I recall a very unpleasant experience where I = had a perfectly fine sync function in JS that I needed to modify to incl= ude an IO call, which required rewriting 5 functions and touching a doze= n more. That's what I think we all want to NOT have in PHP. Third: So my question would be, is there a practical middle-ground? Is = there a syntax and semantics we could define that would cover *most* edg= e cases existing code may have involving shared mutable state automatica= lly, and have some manual way of handling the rest that doesn't require = updating 17 functions, some of which may not even be my code? Would tha= t be "safe enough"? Is there a "safe enough"? I am still on team "structured concurrency only or bust" myself, though = I admit that doesn't fully resolve the issue. But the particular questi= on here is how to indicate where suspension may occur; the RFC right now= says "any IO operation, implicitly, hope that's OK." Which is both ver= y convenient and potentially dangerous. But the status quo today of "no= IO operations, which means you have to write your own IO libraries from= the socket level up, GFL" is, obviously, not a great time. Just completely spitballing, so possibly awful idea but maybe it will ma= ke someone else think of a better one: Colored functions to opt-in to su= spension but do NOT propagate that dependency up. Something like, if yo= u prefix a function call with `await` or `async`, then you could suspend= there; you're explicitly telling the engine you're OK with suspending h= ere if it wants to. If there's no other coroutines active it behaves ex= actly (and in this case, actually exactly) as it would today, so there's= no cost to add it. It would also work on non-IO functions, so long-run= ning CPU-bound processes could opt-in to "hey, I'm taking a long time, i= f you want to jump in here that's safe." However, you're NOT limited to= using that keyword inside a marked function. You can use it on any cal= l to file_get_contents(). However, a function can also declare itself `= sync`, which will override that opt-in for the entire call stack down. = Basically it disables the suspend operation. So if you have a tricky bi= t of global-using code, you can opt it out of switching without having t= o rewrite the world. In code, it would look something like: function log(string $m) { // We're explicitly *allowing* the scheduler to swap out here, // but it doesn't have to. async file_put_contents('log.txt', $m, FILE_APPEND); } function first() { // Do work. // This call may end up switching to another coroutine for a while, or= not, we don't care. // Importantly, we don't need to "color" first() for it to work. log('Did work'); } sync function second() { // Nothing inside here will swap to another coroutine, even though log= () // contains an async call inside it. The code behaves as if that=20 // keyword is just not there. log('starting work.'); // Do work. log ('finished work."); } This would mean that IO suspension becomes opt-in by default, so most IO= -heavy libraries are not going to benefit from any async until they're u= pdated. But that seems it may be safer than just assuming they're safe = or else "oops, you're screwed on 8.6 until you add some new 8.6-specific= syntax, sorry." (Being able to write code that runs correctly in two, = ideally several, versions is crucially important for BC.) As I said, this is just me spitballing so there may be a very good reaso= n why it can't work; I'm just trying to brainstorm a way out of the devi= l's dichotomy of "you have to rewrite all of your code to have no shared= mutable state, even though you don't know what shared means, sorry" vs = "your code may work, probably, but we're not sure, there could be subtle= bugs that are hard to find, sorry." Neither of which seems like good o= ptions. --Larry Garfield