Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129125 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 597591A00BC for ; Fri, 7 Nov 2025 05:24:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1762493083; bh=nIl+oG/y5RpR7BX0h7Ey0ZdImcU1+nZ8hnLzPJ9yu5w=; h=Date:To:Subject:From:From; b=hFefjOCiDU6FUkC9WkKfsGt1hK9he733o/q/yjgo6vryOQjLj8/DzSA2/09Zu7j5q RY9//THRoGMKPiOz+DvBiyQ/mbkbEn9t9ix83Pzq+DsZ/mgjoIZ/jxJeOJSK9yWkn4 L9aQZueMYOoZ9hRC1AGD8Zxx+I9mefomop0Itdhu62FfiTRLgg2OWsSAJLwGc05UhK i5QszTeAYTTUr/8KStRj6WZQC/+l+renqBRjL8/sbMDuK7VHUYUVnSz54cGiIvW+Cl FKXPN4KVMBf0RuRjn8v4idVLfIQecmZM3M7zpSj5b3vWChK1+9e6zY7jUwyH8ANZZO pjHfjudjIwoJw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id B05C81801E4 for ; Fri, 7 Nov 2025 05:24:39 +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_H3,RCVD_IN_MSPIKE_WL, 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-ot1-f50.google.com (mail-ot1-f50.google.com [209.85.210.50]) (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 05:24:39 +0000 (UTC) Received: by mail-ot1-f50.google.com with SMTP id 46e09a7af769-7c2948b774cso238470a34.0 for ; Thu, 06 Nov 2025 21:24:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1762493073; x=1763097873; darn=lists.php.net; h=from:content-language:subject:to:user-agent:mime-version:date :message-id:from:to:cc:subject:date:message-id:reply-to; bh=iTbzZTC9c8Ze3SSJiqjJICN1iRJMIyF0QnZwt2t/5d8=; b=dyH5u+6RYMNQ+EBMQwYFjf3pGPSGCPXNRNdn82eziDrPrcPMcKOyX+rqjoWPEONIhM z57Ab+2FYlnD2CXEwhCd8xEBs1rrPdLacwi2HDxVQX9AFInXphOnT2/m8oEWN4J4Lafb TN7BgtB1wmqzjcXIHHxcPI+t9jTkfJ+KCPfhWtuSO4Aa04VBkS0kHrruZltoRA4Vcz74 toxgaeO9Oz5/k+JaGKF0SF4FrPYZbdI3tNUpK2PAmrSO9lqRkjjnNbu9/Xue8Jf9FXDf U9YnTjXksbnNaRB/h6nsE2MLM70BijcOUCMn5Ll/9r2MuBuUktSgMt7DgPVxhzDypX+M 4/KA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762493073; x=1763097873; h=from:content-language:subject:to:user-agent:mime-version:date :message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=iTbzZTC9c8Ze3SSJiqjJICN1iRJMIyF0QnZwt2t/5d8=; b=QP4daCOQxkAW4iFqb73DaJv1i0hHDRsVXp3JasWj11NWiKmybFlY4xV/Ud9+Zc9kKp CZ6XaOmpEh8U7GARDn15rcY7KJUpXv1RtORaoxFFNh1NBkiKM0MwcqvNfeE7UIj9gcvH zspj13zEIyWp1aANtAosUE6JBY7I3AytEPpWrQ7AD6yUe/HJJ/S7RZPyRLIpFNww3rDL FjKaZMx4rxKhbpb3mECsRcbyJOqKPWikeCNLnWGfrkxtCeG2voZsa718+oP1DdAzikOI 3qT41lqiQ3SkeZKn3f8RSUeu+ULNYAWz5i1TkVTNGsK2JXKWAaygB43EZ1Av1wodVmJL sxJA== X-Gm-Message-State: AOJu0YwToXYEYotGUjvjcqFTnOyrsyPTPMIPrUv65L2E01DIQlCCPpzs 2MWv5wDC3kUKv0SNn8qsxCP5RSwJ9SWh39e8J+9eY1r73aYH4AZL52uHn6Euqg== X-Gm-Gg: ASbGncuABrORKdZtgA2tntkSVC3N4tzftKKRnOPL1I+LIJTNtDm3pJSaEMrjb8TOWOR Y0o/GAEDSCkhce6SKV80qmXq7qItic345BQXc4DF0z+cSLsZZ0WG4P2ViSr1pr+RUq1X+QpR4q2 2ngzejEsuDYc4NlJQgKC/B6kl4DbByN/jqZ7bvjVuPU77YhJEjJ6f/hNGcH8wHb1cwsCdLN9V8l iDMwv+Kt6wBt3kRkeqhQ29cBy5MdUJeT6D+E2RShOj9T91hdq9oTvbADMETBvVUIUYe71Nyj66a Mmgj6OY2/J/fCbhZyT0w9n3GmZoDBS4zXtx1NNggUGZ7JAxAiu/CVF/3ZJwBsogppLAgUOV4S5n O/QLfIuZkYGuYFmzwCGnN1vbiKii3Ml3AtRNJpKmLCfwblZr/II18JkY4/xbzWZmgAqElEpiylq WKGODUgVUAjVrIWxPGjrPzVJIgkZ4Jsf4pykWW3nXkqSe/inMhMRWVsnrUcAL7hvAifO4O X-Google-Smtp-Source: AGHT+IFDPKacRk9IsXTUz2ILTmpFN2AUMg2vNogCBXHMSnYetQRAfrp1SeW8k6w41pVD3TtUyxAfdw== X-Received: by 2002:a05:6830:25c6:b0:7b0:6c2e:7c13 with SMTP id 46e09a7af769-7c6efdcfac3mr1760899a34.16.1762493073111; Thu, 06 Nov 2025 21:24:33 -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 46e09a7af769-7c6f0f0b289sm854432a34.2.2025.11.06.21.24.29 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 06 Nov 2025 21:24:31 -0800 (PST) Content-Type: multipart/alternative; boundary="------------DMf0M0lXPeyoYIyx4OI8Gs6f" Message-ID: Date: Fri, 7 Nov 2025 02:24:27 -0300 Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 User-Agent: Mozilla Thunderbird To: internals@lists.php.net Subject: [PHP-DEV] Re: PHP True Async RFC Stage 5 Content-Language: pt-BR 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. --------------DMf0M0lXPeyoYIyx4OI8Gs6f 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. | *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 On Thu, 30 Oct 2025 08:19:40 +0000, Edmond Dantes wrote: > Hi > > 1.5 RFC: > https://wiki.php.net/rfc/true_async > > Here’s the fifth version of the RFC with the updates made after the > 1.4 discussion. > > Starting from 2025-11-03, there will be a two-week discussion period. > > **Changelog:** > > * Added FutureLike interface methods: cancel(), isCompleted(), isCancelled() > * Renamed Coroutine::isFinished() to Coroutine::isCompleted() > * Clarified exit/die behavior: always triggers Graceful Shutdown mode > regardless of where called > * Added rationale for “Cancellable by design” policy: explains why > default cancellability reduces code complexity for read-heavy PHP > workloads > * RFC structure improvements: reorganized Cancellation section with > proper subsections hierarchy > * Moved “Coroutine lifetime” as subsection under Coroutine section > * Extended glossary with Awaitable, Suspension, Graceful Shutdown, and > Deadlock terms > * Introduced FutureLike interface with single-assignment semantics and > changed await() signature to accept FutureLike instead of Awaitable > for type safety > * Split RFC: Moved Scope and structured concurrency functionality to > separate Scope RFC. Base RFC now focuses on core async primitives > (coroutines, await, cancellation) > > I decided not to wait until Monday and made the changes today. If > anyone has read version 1.4 and has comments on it, they’re still > relevant. > > The Scope API has been moved to a separate RFC: > https://wiki.php.net/rfc/true_async_scope > > ---- > Best Regards, Ed --------------DMf0M0lXPeyoYIyx4OI8Gs6f 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.

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

On Thu, 30 Oct 2025 08:19:40 +0000, Edmond Dantes wrote:

> Hi
>
> 1.5 RFC:
> https://wiki.php.net/rfc/true_async
>
> Here’s the fifth version of the RFC with the updates made after the
> 1.4 discussion.
>
> Starting from 2025-11-03, there will be a two-week discussion period.
>
> **Changelog:**
>
> * Added FutureLike interface methods: cancel(), isCompleted(), isCancelled()
> * Renamed Coroutine::isFinished() to Coroutine::isCompleted()
> * Clarified exit/die behavior: always triggers Graceful Shutdown mode
> regardless of where called
> * Added rationale for “Cancellable by design” policy: explains why
> default cancellability reduces code complexity for read-heavy PHP
> workloads
> * RFC structure improvements: reorganized Cancellation section with
> proper subsections hierarchy
> * Moved “Coroutine lifetime” as subsection under Coroutine section
> * Extended glossary with Awaitable, Suspension, Graceful Shutdown, and
> Deadlock terms
> * Introduced FutureLike interface with single-assignment semantics and
> changed await() signature to accept FutureLike instead of Awaitable
> for type safety
> * Split RFC: Moved Scope and structured concurrency functionality to
> separate Scope RFC. Base RFC now focuses on core async primitives
> (coroutines, await, cancellation)
>
> I decided not to wait until Monday and made the changes today. If
> anyone has read version 1.4 and has comments on it, they’re still
> relevant.
>
> The Scope API has been moved to a separate RFC:
> https://wiki.php.net/rfc/true_async_scope
>
> ----
> Best Regards, Ed

--------------DMf0M0lXPeyoYIyx4OI8Gs6f--