Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129422 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 338FD1A00BC for ; Mon, 24 Nov 2025 00:26:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1763943965; bh=C5W08g0vr+pb5N+hW98a0OgtFO3Ldm9gacQH3sSVrM4=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=b1J9j/QYsjOoXP5b0OW42r5/ISQR9tUrz7OFdiKTJYv+UyRM23kd16oBnUMCkhiUW E24KZdGNZnjKjur890yMQhIkuOlleX5RZY8vU1JLspinKfezRLOurn2HLm5RYrYv5V GlM+72aVyFcjbav0IlhK/Isx6StS9CUfAQD+4nsDedKRr0DgnsdM1uw997Z2Pk3kDP 6ZFKv+kOL42V8uCedgQrMGJc9PvrFdhIInjLjfhc8i+0+uikEe2Zh+ph2+Ry2Gw/a0 VahRuNCkEM7deR5/TZ4x48NOwCEwnICmEiz1eiqlJPVq04Jg7EyO32r9efQ1FggB68 oFV4mD+aTH7Yw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 7C2AC180055 for ; Mon, 24 Nov 2025 00:26:04 +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,FREEMAIL_FROM, 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-lf1-f48.google.com (mail-lf1-f48.google.com [209.85.167.48]) (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 ; Mon, 24 Nov 2025 00:26:04 +0000 (UTC) Received: by mail-lf1-f48.google.com with SMTP id 2adb3069b0e04-5957753e0efso3892767e87.1 for ; Sun, 23 Nov 2025 16:25:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763943958; x=1764548758; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=gEYPvW7PpcZvea6lzRBWGmcUzkeWwy5MYiN1UmJPRZw=; b=lejeVApx7aplj3Vi8FJ5+516InHq236zxohgSa95YSha0256Mg53TllSL/LxS+ikPr gElvyxsyWLoodYc7q7AKZe3/y0+5rHYVBRz8czK7ynWJ8wg15KFHEjnWdvpmZIT4wmzQ QyZJfnWumqCDgShtHxNCskeFL5qMt6OanRphHJvpPpd6Ub/Q5/OpJY6fu45dHXW4oY8G fEA/fW1on1/tbugjLsAdZe1C1LZceZrW5wojZxzK8HUaDgC1ITqhEpUigrdl04WNZcf1 DPNrLAmpjAOmFnBhCX9ixo2PqnNppDGWyOqieH74qNrwgYlf7xdN4Q5KDO0t21K8EUWF M/pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763943958; x=1764548758; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=gEYPvW7PpcZvea6lzRBWGmcUzkeWwy5MYiN1UmJPRZw=; b=ezSE702JkDXhP7Clf0Su41j6ziksWE4Ud+4WOBzmCVTWRxdH4qLkPTlMJ3HsAL3NRH 3xc1Kr2dZX0sr+2EILvmKc3A9UzLKr2ysacJvi6dBkZieGC6b4Iqr512VJhNvjfHtkQz 5Z72PRsZXZq+MXTmVKis0tidenyN8sHSNezwOl5LPSczExEKFm9YghcSPTsbTpJuRvb3 K7c9XXRPfbGdd0wBmFHF6OuSSz9EDEfatx9EpH1Yun5Xoa9mWP/1w0aATv9biEh/4Mec 6L9ckdUPYp9mgAeiXNchlIg2Niwfj13ZWWqPssRh2Muu4+Gj8vC6+d6fQjM+5uFCikyc aamg== X-Gm-Message-State: AOJu0Yx5ms4ro84eTnYk7+ZQXRWzdp3dI9CjU2pV0155uQPYUzRhGc25 AJCWlmyeJM1SNcdFzoHNm488l1WkKuCC9809oO43aosNuN9JobOSXqnTlVSjdrNojFnmo24ux/f qVBUiwxlSMIIdp2um9x+97ksgzjsVoGbYrnsjscQ= X-Gm-Gg: ASbGnctnNNs5boZpv89dBo8gVK0iRzsTt0ivGK0zxT+jbkLCkpfZ3mwshfR5SuJnYNl zKtTQbCUQLq2beFqeA7KzeXNhMq92V3Z3EmNXZBpfF1W6gbpPjvY55vqt2e5NsYzNA+XKWY4dMz a5x9uKwc3tiCFRBAPr/TjJKTsA7hhbFnY2Y/6AT6zDWUaqvOYunD6P4v4IyXxf07a1jCusGwt39 sdJDbttyjeAa4NP04BEYnDk4ZbraNnxTScskaqgBXHZjFv0ShL62caYt2o6//tsrIZqgKfuqGDz ikPs/UIl6Cdrf4utsAyyfmXTIsyk+G9ep85skDo= X-Google-Smtp-Source: AGHT+IFxQfQWW5qhP/cBmCELTAasZbD6CRqMc18wsoolI9D43D5kzgD9tB1TDmS4FAE6JZgFBXb0FmMilVv8W/H1nco= X-Received: by 2002:a05:6512:3188:b0:594:2835:e73e with SMTP id 2adb3069b0e04-596a3edddf5mr3865295e87.37.1763943957244; Sun, 23 Nov 2025 16:25:57 -0800 (PST) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: <691963327.399484.1763796022993@email.ionos.de> <1402906904.784903.1763811759896@email.ionos.de> <2015208655.784984.1763811978476@email.ionos.de> <980296152.1071.1763813573083@email.ionos.de> <92865666.4510.1763818506332@email.ionos.de> <329450798.8037.1763822426377@email.ionos.de> <9287c46c-bc63-4dd0-9792-0f9421959589@rwec.co.uk> In-Reply-To: <9287c46c-bc63-4dd0-9792-0f9421959589@rwec.co.uk> Date: Sun, 23 Nov 2025 21:25:43 -0300 X-Gm-Features: AWmQ_bnRmkgPr6dkmdIVvqYH1-OTCsxMPlU6WJ_Am8sPU9av2mJQOTZGTH3_miE Message-ID: Subject: Re: [PHP-DEV] [VOTE] True Async RFC 1.6 To: "Rowan Tommins [IMSoP]" Cc: internals@lists.php.net Content-Type: multipart/alternative; boundary="000000000000f9add006444c34f8" From: luisvscbarros@gmail.com (=?UTF-8?Q?Lu=C3=ADs_Vin=C3=ADcius_Santos_da_Costa_Barros?=) --000000000000f9add006444c34f8 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hello, I have serious concerns about any approach that may cause the event loop to block. The correct ways to handle this should not involve blocking the loop =E2=80=94 whether globally or in a scoped manner =E2=80=94 while attempting= to let synchronous and asynchronous code coexist in the same environment. More appropriate alternatives would be offloading execution to another thread (which is far too complex for the current VM and ecosystem) or relying on preemption (which is not feasible to implement here). In addition, the cascading effects of such an approach are significant: libraries would be forced to implement internal mechanisms just to deal with unexpected loop stalls and similar issues. It would be much healthier for new libraries to be designed specifically for the asynchronous environment, in the same way Laravel created Octane to run on top of Swoole. Kind regards, Lu=C3=ADs Vin=C3=ADcius. Rowan Tommins [IMSoP] escreveu (domingo, 23/11/2025 =C3=A0(s) 18:58): > On 23/11/2025 19:09, Edmond Dantes wrote: > > @Ed Unless something calls `spawn` all I/O is going to be blocking & > non-concurrent, correct? > > Yes. > If no one calls spawn, this is equivalent to the code running inside a > single coroutine. > > At the moment, TrueAsync has an internal flag that allows it to be > enabled or disabled. If Async is disabled, an exception will be > thrown. > > > I think there's a lot of confusion in this thread because different peopl= e > are talking about different scenarios. Perhaps it would be useful to > introduce some User Stories... > > > Async Alice is working on a brand new application written in PHP 9, and i= s > designing it from the ground up to make use of async capabilities whereve= r > possible. She wants third-party libraries to use async I/O so that she ca= n > use them in her design. > > Beginner Bob has a recently built application, and thinks there's an > opportunity to improve it with async I/O, but doesn't know anything about > it. He wants a simple-to-use API that lets him get the benefits, and clea= r > instructions on what pitfalls to look out for. > > Legacy Les is maintaining a 20-year-old business back office system, whic= h > makes extensive use of global state and does not have good automated > testing. He wants to run it under PHP 9, and to use up-to-date third-part= y > libraries for new functionality, without an expensive and risky rewrite o= f > existing code. > > Finally, SDK Susie is publishing the official PHP library for a popular > cloud API. She wants to serve the best version she can for Alice, Bob, an= d > Les, but doesn't want to maintain separate "sync" and "async" branches of > the library or its methods. > > Feel free to create more personas if you want to talk about additional > scenarios. > > > The first thing I want to clarify is that SDK Susie doesn't necessarily > need to change the public methods of her library; she can still use async > I/O internally. For instance, if a method already returns an Iterator to > silently fetch a page of results at a time, that can be changed to store > Promises internally, and await them when the data is needed. > > However, she might want to mark it as a breaking change anyway, so > that Async Alice and Beginner Bob know they are opting into it. > > > Legacy Les won't get it until he opts in, but at some point he will need = a > new version of the library for other reasons (e.g. because the cloud API > becomes incompatible with the old library version); so he still needs a w= ay > to run it safely. > > If he runs PHP in a mode where any attempt to use async I/O *throws an > error*, he still can't use the new version of the library, so this doesn'= t > help him. > > > However, if Legacy Les can run PHP in a mode where any attempt to use > async I/O is *automatically run synchronously*, then he will be happy: he > can run his legacy application under PHP 9, and use the updated library, > without worrying about async code. > > Beginner Bob doesn't want to run his whole application in "sync only" > mode, but might want to switch *parts of it*, so that he doesn't have to > think about them yet. So a scoped, rather than global, switch might be > useful for him. > > > This is how I picture that mode working: when SDK Susie's library code > calls "spawn", a Coroutine is created as normal. However, when it suspend= s, > the Scheduler immediately resumes it, rather than switching to a differen= t > Coroutine. The library code will see the Coroutine object it expects, but > passing it to "await" will immediately produce its result. > > However, I might well be misunderstanding something, and this is either > impossible or difficult to implement. If so, I think some other solution = to > Legacy Les's requirements is needed. > > > I hope this description is useful. > > > -- > Rowan Tommins > [IMSoP] > > --000000000000f9add006444c34f8 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hello,

I have serious concerns abo= ut any approach that may cause the event loop to block. The correct ways to= handle this should not involve blocking the loop =E2=80=94 whether globall= y or in a scoped manner =E2=80=94 while attempting to let synchronous and a= synchronous code coexist in the same environment. More appropriate alternat= ives would be offloading execution to another thread (which is far too comp= lex for the current VM and ecosystem) or relying on preemption (which is no= t feasible to implement here).

In addition, the cascading effects of= such an approach are significant: libraries would be forced to implement i= nternal mechanisms just to deal with unexpected loop stalls and similar iss= ues.

It would be much healthier for new libraries to be designed spe= cifically for the asynchronous environment, in the same way Laravel created= Octane to run on top of Swoole.

Kind regards,
Lu=C3=ADs Vin=C3= =ADcius.

Rowan Tommins [IMSoP] <imsop.php@rwec.co.uk> escreveu (domingo, 23/11/= 2025 =C3=A0(s) 18:58):
=20 =20 =20
On 23/11/2025 19:09, Edmond Dantes wrote:
@E=
d Unless something calls `spawn` all I/O is going to be blocking &
non-concurrent, correct?
Yes.
If no one calls spawn, this is equivalent to the code running inside a
single coroutine.

At the moment, TrueAsync has an internal flag that allows it to be
enabled or disabled. If Async is disabled, an exception will be
thrown.


I think there's a lot of confusion in this thread because different people are talking about different scenarios. Perhaps it would be useful to introduce some User Stories...


Async Alice is working on a brand new application written in PHP 9, and is designing it from the ground up to make use of async capabilities wherever possible. She wants third-party libraries to use async I/O so that she can use them in her design.

Beginner Bob has a recently built application, and thinks there'= s an opportunity to improve it with async I/O, but doesn't know anything about it. He wants a simple-to-use API that lets him get the benefits, and clear instructions on what pitfalls to look out for.

Legacy Les is maintaining a 20-year-old business back office system, which makes extensive use of global state and does not have good automated testing. He wants to run it under PHP 9, and to use up-to-date third-party libraries for new functionality, without an expensive and risky rewrite of existing code.

Finally, SDK Susie is publishing the official PHP library for a popular cloud API. She wants to serve the best version she can for Alice, Bob, and Les, but doesn't want to maintain separate "= sync" and "async" branches of the library or its methods.

Feel free to create more personas if you want to talk about additional scenarios.


The first thing I want to clarify is that SDK Susie doesn't necessarily need to change the public methods of her library; she can still use async I/O internally. For instance, if a method already returns an Iterator to silently fetch a page of results at a time, that can be changed to store Promises internally, and await them when the data is needed.

However, she might want to mark it as a breaking change anyway, so that=C2=A0Async Alice and Beginner Bob know they are opting into i= t.


Legacy Les won't get it until he opts in, but at some point he will need a new version of the library for other reasons (e.g. because the cloud API becomes incompatible with the old library version); so he still needs a way to run it safely.

If he=C2=A0runs PHP in a mode where any attempt to use async I/O *throws an error*, he still can't use the new version of the library, so this doesn't help him.


However, if=C2=A0Legacy Les can run PHP in a mode where any attempt = to use async I/O is *automatically run synchronously*, then he will be happy: he can run his legacy application under PHP 9, and use the updated library, without worrying about async code.

Beginner Bob doesn't want to run his whole application in "= sync only" mode, but might want to switch *parts of it*, so that he doesn't have to think about them yet. So a scoped, rather than global, switch might be useful for him.


This is how I picture that mode working:=C2=A0when SDK Susie's l= ibrary code calls "spawn", a Coroutine is created as normal. Howev= er, when it suspends, the Scheduler immediately resumes it, rather than switching to a different Coroutine. The library code will see the=C2=A0Coroutine object it expects, but passing it to "await&q= uot; will immediately produce its result.

However, I might well be misunderstanding something, and this is either impossible or difficult to implement. If so, I think some other solution to Legacy Les's requirements is needed.


I hope this description is useful.


--=20
Rowan Tommins
[IMSoP]
--000000000000f9add006444c34f8--