Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126633 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 qa.php.net (Postfix) with ESMTPS id 25E9A1A00BC for ; Sat, 8 Mar 2025 08:06:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1741421020; bh=E3fW+Eh7rVDRGcEg2tezcqPJJ/id6isz1TuNad2j7tw=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=fKeHTcCYlXd/B4XnmkUtxKNyePy4HuRDNFKVyTr6SQ3ONhi6nISDPSxtVKz7Ax+Bt wEUz8rT7GGSXBVYumN8AHQGIDQkBFXQtaDUkEclZ+R+aRDGEDW9tWdls3mArw6zCC5 Cft/lRuFpe1GpvSoQwtwpb2nXHWbUtFJepheufkC0NJrNYvu4qAEnHdweu+ZExWfo1 tYi6PjCTHPlesvolEI4gqT4OOIqwURVjsVWiKA3mEoqJNyCJxeF01hPupTzOqemh8V D/CmvaYhY0tMwfNaxSGQMGviDtyxJiZTfUK4HP3OJNk18p7VdKWmPrdlevqIxlqaOj FpxS5IDvw4+ng== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id C3844180034 for ; Sat, 8 Mar 2025 08:03:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_20,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.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-yb1-f177.google.com (mail-yb1-f177.google.com [209.85.219.177]) (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 ; Sat, 8 Mar 2025 08:03:39 +0000 (UTC) Received: by mail-yb1-f177.google.com with SMTP id 3f1490d57ef6-e549be93d5eso2382355276.1 for ; Sat, 08 Mar 2025 00:06:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741421174; x=1742025974; 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=E3fW+Eh7rVDRGcEg2tezcqPJJ/id6isz1TuNad2j7tw=; b=Kj6t7yhWwxq+l2hYwVis9Yy2Lc85tCX+zSDMt5/AExI+6U6dlStj0k9PerckQTsyod eo1xS46uo15roMhMBnX+7v0RBNP3POsiYtlDNjRiZN544OpRRgrToCyzOV3kpA4Iev0R ARodjLWUKxJ41Zt05d/31a2xZEGyAc9rvfrRTGPtjAj9tNm2K/HEYS59snQdgKFe4pIX Tv4WxSIdNLQ5BmRVqGG5Hol8kCHMcoMQIkTCGKvfJH1WZWvPhifT8j+K+dvlmFVqUOHT PATf7bL221ET0VTpCTWwHlsX49crk8kynTN1Hf6Qkg0ihm7MHWZR6fSuoEpPTHw9Zalx ApRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741421174; x=1742025974; 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=E3fW+Eh7rVDRGcEg2tezcqPJJ/id6isz1TuNad2j7tw=; b=uC3AfoQFx/3bfPBqZyoqalS1Rh3XRSoVKvOlZ0JpUDUNwqh4VH+7jfQJ9Q1nkY7eAy XK/HoNvOZ8rEF57oHNAckAn9kzx+kzkluXByMmoq3LmWGwSs0JtTnOwWN5mAMhrfAfp+ dhvphZFlqnCbHHMZ/GE6TaNm/hnlEH4gvFp7+xGXViTAd78Fnqge8TrbboQ6gQHKkygM FgwC4emwEwFJEEThitMBU8m49itBS3w5Oq+TSdZLaWoVFs5rmXEdpwELOBZNxruVdwzm jT5d8kwkvkK3uG+HQVS1PvKR3RVkv4S1em3md2rcHk5wqCbJ0jjfCO9tVWbnf7IgMVKt c6hA== X-Gm-Message-State: AOJu0YxRSzQacaVg7DpIB9fmtqbMtk18sEANgwOhF3b3mI+eSSxur9pM IcSjzlTtPSgremEn5J2p+ETFDk6ZtRD4F1m+pIHNIxjQ1mPWlYB2812f4/EV2NgDIrZG1LgfOZJ utA5KK1h2Tl8TcAqaiijp7wwTSCdoyw== X-Gm-Gg: ASbGncuSfaLrxtk7gLLb4rC2SG8QlA81EISRzCvRNJHZrHP2J5GinJKtKULG/pzYTIt uF6NItyljZ7R0rjyj5GN71xSXFZZMZjFZWC69g6E+C/3jsWwd18USRnb1uX3A4xuhO2eXfBvgND SR+ndm5+EVDigBXYksIJXOznUnddxh X-Google-Smtp-Source: AGHT+IH1KkFD6T6Eq1HBcwZxSSrup0M3WExknXUMg1AjqU2dZQyq6MF603p2BwbPJtiPEExAkMwvlJkvolu5wXT06tg= X-Received: by 2002:a05:6902:701:b0:e5a:ca6b:4531 with SMTP id 3f1490d57ef6-e635c13860fmr7948846276.12.1741421173653; Sat, 08 Mar 2025 00:06:13 -0800 (PST) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <9964db8c-0ffe-43d5-8246-47fc76b07180@app.fastmail.com> <78a03dd0-fd4a-4f4a-ad8a-37e5704f06fc@app.fastmail.com> <08c8ad0b-e8f4-46e3-99f0-b80748d40b89@app.fastmail.com> <07973EAE-2D83-47A8-8FA0-84286C77C02B@rwec.co.uk> <48d66433-3ae9-4895-8361-7c81a0a3670d@app.fastmail.com> In-Reply-To: Date: Sat, 8 Mar 2025 10:06:02 +0200 X-Gm-Features: AQ5f1JpG0FG_7L5_6ecta7KvidgCTmjt6C8EjxDhFI93xOrVcbrwuMPxfUtkjIk Message-ID: Subject: Re: [PHP-DEV] PHP True Async RFC To: Rob Landers Cc: PHP Internals Content-Type: multipart/alternative; boundary="00000000000075cefc062fd03624" From: zsidelnik@gmail.com (Eugene Sidelnyk) --00000000000075cefc062fd03624 Content-Type: text/plain; charset="UTF-8" > > > The uncoloring of functions in PHP is probably one of the most annoying > aspects of fibers, IMHO. It's hard to explain unless you've been using them > awhile. But, with colored functions, the caller has control over when the > result is waiting on -- it could be now, it could be in a totally different > part of the program, or not at all. With fibers, the author of the function > you are calling has control over when the result is waited on (and they > don't have control over anything they call). This can create unpredictable > issues when writing code where a specific part wrote some code thinking it > had exclusive access to a property/variable. However, someone else changed > one of the functions being called into an async function, making that > assumption no longer true. > > With colored functions, the person making changes also has to update all > the places where it is called and can validate any assumptions are still > going to be true; uncolored functions means they almost never do this. This > results in more work for people implementing async, but more correct > programs overall. > > But back to the awaiting on results. Say I want to read 10 files: > > for ($i = 0; $i < 10; $i++) $results[] = file_get_contents($file[$i]); > > Right now, we have to read each file, one at a time, because this is > synchronous. Even with this RFC and being in a fiber, the overall execution > might be non-blocking, but the code still reads one file after another > sequentially. Fibers do not change this. > > With this RFC (in its original form), we will be able to change it so that > we can run it asynchronously though and choose when to wait: > > for($i = 0; $i < 10; $i++) $results[] = async\async(fn($f) => > file_get_contents($f), $file[$i]); > // convert $results into futures somehow -- though actually doesn't look > like it is possible. > $results = async\awaitAll($results); > > In that example, we are deliberately starting to read all 10 files at the > same time. If we had colored functions (aka, async/await) then changing > file_get_contents to async would mean you have to change everywhere it is > called too. That means I would see that file_get_contents is synchronous > and be able to optimize it without having to even understand the reasoning > (in most cases). I was a user of C# when this happened to C#, and it was a > pain... So, at least with PHP fibers, this won't be AS painful, but you > still have to do some work to take full advantage of them. > > I kind of like the idea of a nursery for async, as we could then update > file_get_content's return type to something like > string|false|future. In non-async, you have everything behave > as normal, but inside a nursery, it returns a future that can be awaited > however you want and is fully non-blocking. In other words, simply > returning a future is enough for the engine to realize it should spawn a > fiber (similar to how using yield works with generators). > > In any case, I believe that a nursery requires the use of colored > functions. That may be good or bad, but IMHO makes it much more useful and > easier to write correct and fast code. > In my opinion, colored functions is the worst thing that could happen to PHP. https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function Describes quite expressively what's wrong about this approach. As the result, you will make everything async. Want a repository? It will be all async. Want a logger? Also async. Need to cache something? Make it async. This is going to be a ton of changes, when currently sync (blue function) will have to become async (red one). The way amphp goes - it's the right way. They have had this problem of red-blue functions a long ago until Fibers came into place. What they used until third version is generator-based coroutines, so that instead of returning actual object, you spoil the signature of the function and return generator that will return that object (iow, "Promise"). This is just annoying, and IMO should not be considered. --00000000000075cefc062fd03624 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

=
The uncoloring of functions in P= HP is probably one of the most annoying aspects of fibers, IMHO. It's h= ard to explain unless you've been using them awhile. But, with colored = functions, the caller has control over when the result is waiting on -- it = could be now, it could be in a totally different part of the program, or no= t at all. With fibers, the author of the function you are calling has contr= ol over when the result is waited on (and they don't have control over = anything they call). This can create unpredictable issues when writing code= where a specific part wrote some code thinking it had exclusive access to = a property/variable. However, someone else changed one of the functions bei= ng called into an async function, making that assumption no longer true.

With colored functions, the person making change= s also has to update all the places where it is called and can validate any= assumptions are still going to be true; uncolored functions means they alm= ost never do this. This results in more work for people implementing async,= but more correct programs overall.

But back t= o the awaiting on results. Say I want to read 10 files:

<= /div>
for ($i =3D 0; $i < 10; $i++) $results[] =3D file_get_contents= ($file[$i]);

Right now, we have to read each f= ile, one at a time, because this is synchronous. Even with this RFC and bei= ng in a fiber, the overall execution might be non-blocking, but the code st= ill reads one file after another sequentially. Fibers do not change this.

With this RFC (in its original form), we will b= e able to change it so that we can run it asynchronously though and choose = when to wait:

for($i =3D 0; $i < 10; $i++) = $results[] =3D async\async(fn($f) =3D> file_get_contents($f), $file[$i])= ;
// convert $results into futures somehow -- though actually= doesn't look like it is possible.
$results =3D async\awa= itAll($results);

In that example, we are delib= erately starting to read all 10 files at the same time. If we had colored f= unctions (aka, async/await) then changing file_get_contents to async would = mean you have to change everywhere it is called too. That means I would see= that file_get_contents is synchronous and be able to optimize it without h= aving to even understand the reasoning (in most cases). I was a user of C# = when this happened to C#, and it was a pain... So, at least with PHP fibers= , this won't be AS painful, but you still have to do some work to take = full advantage of them.

I kind of like the ide= a of a nursery for async, as we could then update file_get_content's re= turn type to something like string|false|future<string|false>. In non= -async, you have everything behave as normal, but inside a nursery, it retu= rns a future that can be awaited however you want and is fully non-blocking= . In other words, simply returning a future is enough for the engine to rea= lize it should spawn a fiber (similar to how using yield works with generat= ors).=C2=A0

In any case, I believe that a nurs= ery requires the use of colored functions. That may be good or bad, but IMH= O makes it much more useful and easier to write correct and fast code.


In my opinion, colored functions = is the worst thing that could happen to PHP.

Describes quite e= xpressively what's wrong about this approach.
As the result, you will make everything async.
Want a repository? It will be all async.
Want a logger? Also async.
Need to cache s= omething? Make it async.

This is going to be a ton of changes, when currently sync (blue function) = will have to become async (red one).

The way amphp goes - it's the right way. They have had thi= s problem of red-blue functions a long ago until Fibers came into place.

What they used until third= version is generator-based coroutines, so that instead of returning actual= object, you spoil the signature of the function and return generator that = will return that object (iow, "Promise").
=
This is just annoying, and IMO should not be co= nsidered.
--00000000000075cefc062fd03624--