Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129126 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 52D2E1A00BC for ; Fri, 7 Nov 2025 06:22:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1762496559; bh=78XTZ+RtTmZ0Ub/AnvNAs022CFlpDBAj+2uKBYZvjb4=; h=Date:From:Subject:To:References:In-Reply-To:From; b=n28Z4lbOY2qR7q7ADXlZLeMk5wvqKrhlBeEGpQmdbnQBnQ69IVesW/46KtLrkP0SO cAYNRfuX5+p906nYsgrFMEKZmv593adavZKYC4fk57xaasu9KLlN6I0ASi/7+y63JK ofjsPVx48vwxXGM/uGz3xA/R7FgqXstRFEl64DRPoFsGIgqVv3RZsUm9u2l20oimM6 JcafYaYxrstXj78W3lBhHZ7UOHKN8OhEHRWs20L6Bo8HO0doE1S2ZIthIOg/qs8ZRa pw8uR8kBJwNVLt2jo4DZgDuX/1bFQ91VojhvwtxQTDzEM9nGGMRX+oFw/YEV2AFaL5 SfzsN73oAVwtA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id E3274180041 for ; Fri, 7 Nov 2025 06:22:35 +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, T_SPF_TEMPERROR autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-oi1-f175.google.com (mail-oi1-f175.google.com [209.85.167.175]) (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 ; Fri, 7 Nov 2025 06:22:35 +0000 (UTC) Received: by mail-oi1-f175.google.com with SMTP id 5614622812f47-450154aa53fso177341b6e.2 for ; Thu, 06 Nov 2025 22:22:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762496549; x=1763101349; darn=lists.php.net; h=in-reply-to:content-language:references:to:subject:from:user-agent :mime-version:date:message-id:from:to:cc:subject:date:message-id :reply-to; bh=AQ0UTRb+R3cvfuxgKHGAK7jp0zKvxTkRG1AeOj/9Jj0=; b=QhSX2kmVGY5Ex+DpialvLkYGfVgchgYyGk+DCN7aFGoWL4fGohcOx9r5yPLz0PYA1v p2xs1zWhcDporIU4h1o+l05OggNH1AfKBok0F4gIdtAdR3pqZcWaYu1iukeIgl/JZoil LAOzzKBqnQWpIsGf7VVc60woyOBRkjVLk4yvugRD7LvApfvlxoVQunp2ILVdEqXiO/sV 20CKV1J8Bu3RdqSR7RJ6+PO9Faeq+DQZfzM5NMXmssT8JGKEwjaG2c1uhqwArWEdfU4d K2ApgsFHld6wnh1Tnng4xSVZj6qkurksiNYrJziO4QPfoFz+jdJu1gq6grvNHm+FTaYg cuPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762496549; x=1763101349; h=in-reply-to:content-language:references:to:subject:from:user-agent :mime-version:date:message-id:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AQ0UTRb+R3cvfuxgKHGAK7jp0zKvxTkRG1AeOj/9Jj0=; b=sgradLU9iSmfRJ3xY/kgk27RyM4NIaXK8bOgkGkAyDS/xK0YNMXM1o/yGlQnmx14BS Sz2p34Y+8UX8cGA15vckCMWAPmS6xRoFk63gtrKuPNDp0eeV/a1LzKQvfKGT0Wjeiv22 wqLhI4WvG0frlyuyFaHD0Mk5E21dM7uEQf91P4xvklNyGb46XhOs9AUJBgsDBMRah9K3 9+tdygqRF0wGtj4TmkF/0p37pPCwwjEPL9I5k9ZoXQGJLREPa/OFQsyQrU9s8jqnOQlu 64fGu9x9wflHD9vH03MKzLPtdxG3K86keKdV6XKgzxjnVjRsKwSemY510xWvgZq05XFO tyHQ== X-Gm-Message-State: AOJu0YzyyJoZ9UNxpz3j51ftnYgMVE5mTFz8Eq2inGv2ZujJTf0QG/7c +0QFQzNzCnP0DcCeXmzRmqejmBod5mrTgWWcn+edGE0fIWuQoxuO9OUERhDH25cW X-Gm-Gg: ASbGncsfDwztJ47wr4dZkdd/FYHCd30dHGMVwVhghNIJ3ERWfQ1k4CsjuFusLP+ZGYH XlqeLV9MKMxeAqB3wCs7FyLyER4xEJO+D9rW8puOY1bI+lockA5ZF5xTJ/6OuXq4aI893F5hihV N/XPXVDC4ZqloHCdXH4vaCbsiMvMCglZRYiF8iEtRCVsdNF45+QLViHtXdEWz9deeqOPBciszuO lFhmtoD8zjWX3F81zgje9csL1imnwZvMk2sWvYmnEm5i4CS/rF1nnzJaQhJLr8o1DK1JIQBXUE7 jZVGH0EIeI13THujavV5Ns5ZP+LKXVTgpI7MbY8hHB26KoWY/So2nxu5fT+50loCrqU21Ol89QU nfON0A0pbFtDzIyILpUaNxccEjecWnKG5vZHQBvkvjeh5ZFFGujb0vd24lhIrwWr5RSuNJvQljw rO8SPtAs6xRH9KsqJFd1NZ77cPEVTjia5QPZqpLtWWYLtY8Q90Ew8nbt2F/keVIGZ7TfGr X-Google-Smtp-Source: AGHT+IFdp8mOPj9ZRxrpnJB3a3i0HpoRFU7q3VXrs0MlUckPjrOl09/XAM9Y6OKPxrJcVilHklT+yQ== X-Received: by 2002:a05:6808:6f8f:b0:450:112c:9aa5 with SMTP id 5614622812f47-45015e0c7ddmr1058022b6e.28.1762496549618; Thu, 06 Nov 2025 22:22:29 -0800 (PST) Received: from ?IPV6:2804:14c:4188:4bf3:95d6:efbd:7bf4:d7d2? ([2804:14c:4188:4bf3:95d6:efbd:7bf4:d7d2]) by smtp.gmail.com with ESMTPSA id 5614622812f47-4500253ce65sm1790278b6e.5.2025.11.06.22.22.28 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 06 Nov 2025 22:22:29 -0800 (PST) Content-Type: multipart/alternative; boundary="------------zn0lN6ALcrFl6d82WLFIfrTW" Message-ID: Date: Fri, 7 Nov 2025 03:22:25 -0300 Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PHP-DEV] Re: PHP True Async RFC Stage 5 To: internals@lists.php.net References: Content-Language: pt-BR In-Reply-To: From: luisvscbarros@gmail.com (=?UTF-8?Q?Lu=C3=ADs_Vin=C3=ADcius_Santos_da_Costa_Barros?=) This is a multi-part message in MIME format. --------------zn0lN6ALcrFl6d82WLFIfrTW Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hi Edmond, First of all, sorry for my bad English, and thanks a lot for the huge amount of work you’ve put into this proposal. You researched, wrote the RFC, implemented it, and answered tons of questions. Really impressive. I have one suggestion and two small questions. *Suggestion* Maybe keep the base |Awaitable| internal and expose two userland interfaces that match the two cases described in the RFC: |// Single state change, idempotent read, same result on each await interface Future extends Awaitable {} // Multiple state changes, each await may observe a new state interface Streamable extends Awaitable {} | This makes the single-shot vs multi-shot difference explicit and easier for tools and libraries to reason about. Later on, it could even be extended with something like: |interface Retryable extends Awaitable {}| *Questions (self-cancellation)* 1. What happens here? |use function Async\spawn; use function Async\suspend; $coroutine = spawn(function() use (&$coroutine) { $coroutine->cancel(new \Async\CancellationError("Self-cancelled")); echo "Before suspend\n"; suspend(); echo "After suspend\n"; // should this run? return "completed"; }); await($coroutine); | Can a cancelled coroutine suspend? And if a function that yields is called after the cancel, should that suspension still happen? 2. And what about this one? |use function Async\spawn; $coroutine2 = spawn(function() use (&$coroutine2) { $coroutine2->cancel(new \Async\CancellationError("Self-cancelled")); echo "Before exception\n"; throw new \RuntimeException("boom after cancel"); }); await($coroutine2); | Which error does |await()| throw in this case — |CancellationError| or |RuntimeException|? It’d be great to clarify that in the docs, since it affects where people put cleanup, logging, etc. Again, thanks for the work, especially on such an important feature for PHP’s future. Hope to see it in php-src soon. Best, *Luís Vinícius* --------------zn0lN6ALcrFl6d82WLFIfrTW Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit

Hi Edmond,

First of all, sorry for my bad English, and thanks a lot for the huge amount of work you’ve put into this proposal.
You researched, wrote the RFC, implemented it, and answered tons of questions. Really impressive.

I have one suggestion and two small questions.

Suggestion

Maybe keep the base Awaitable internal and expose two userland interfaces that match the two cases described in the RFC:

// Single state change, idempotent read, same result on each await interface Future extends Awaitable {} // Multiple state changes, each await may observe a new state interface Streamable extends Awaitable {}

This makes the single-shot vs multi-shot difference explicit and easier for tools and libraries to reason about. 
Later on, it could even be extended with something like:

interface Retryable extends Awaitable {}

Questions (self-cancellation)

  1. What happens here?

use function Async\spawn; use function Async\suspend; $coroutine = spawn(function() use (&$coroutine) { $coroutine->cancel(new \Async\CancellationError("Self-cancelled")); echo "Before suspend\n"; suspend(); echo "After suspend\n"; // should this run? return "completed"; }); await($coroutine);

Can a cancelled coroutine suspend?
And if a function that yields is called after the cancel, should that suspension still happen?

  1. And what about this one?

use function Async\spawn; $coroutine2 = spawn(function() use (&$coroutine2) { $coroutine2->cancel(new \Async\CancellationError("Self-cancelled")); echo "Before exception\n"; throw new \RuntimeException("boom after cancel"); }); await($coroutine2);

Which error does await() throw in this case — CancellationError or RuntimeException?
It’d be great to clarify that in the docs, since it affects where people put cleanup, logging, etc.

Again, thanks for the work, especially on such an important feature for PHP’s future.
Hope to see it in php-src soon.

Best,
Luís Vinícius

--------------zn0lN6ALcrFl6d82WLFIfrTW--