Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126660 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 9C34B1A00BC for ; Sat, 8 Mar 2025 21:42:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1741469994; bh=PzgnlLhGc+mSyx3kNiJMGf2MhQimwCTIZdfrQQrxILM=; h=Date:From:To:In-Reply-To:References:Subject:From; b=bFYnQ8gf1GnMvEXNf2er6Au5KiGHsxbKAQ8yj+Rf8bNDOVzGHGoPKoMmL8Y8ueCcT 6lG1ygaHgQldFZUvzK/53UtvD9/M1Ppnu5hPD8s8uCdtQUW7xfZjsxv39AeE3E46cb hSxWdt3BinOfeJfE3f+q8BS4Tip9jJN19ALHMHBAjRdTRQ8BI85VUeHauvqE9G1MjX MHGjS45y1CzLC/n3F/yerb4z7Ef0sDKXCmuNlT7qzRHVo/DAZoQ9qR2uJto9fYm5WW fNYNnS1aO6Y+nKohKt4OK/tAQs2ihTdXyue97mJUaD5u9TVyY4sgGzXtx1+51Nkj0Y xLc8UK6jsl6qg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 681D31801DA for ; Sat, 8 Mar 2025 21:39:53 +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-ed1-f48.google.com (mail-ed1-f48.google.com [209.85.208.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 ; Sat, 8 Mar 2025 21:39:52 +0000 (UTC) Received: by mail-ed1-f48.google.com with SMTP id 4fb4d7f45d1cf-5dca468c5e4so5575467a12.1 for ; Sat, 08 Mar 2025 13:42:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741470146; x=1742074946; darn=lists.php.net; h=mime-version:subject:references:in-reply-to:message-id:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=WylszkhgGppCdQ9fhwqu5okvvRkAZMoS/mkCg8YcmnY=; b=WnOiR7IxOSpdua2fWKH43JtAJ0IpVXOiXr7LULeThLqtj8sxwXt+eDr3BrUxkKnopg jwS6pYOYpPWUAcLsVAI2bpdZ5XK/bzjGh4bN9ysQXm0PSe2UVE/Bv8fBKbU1xu0pG0An +Ekj8UMW/XeMy3TVkA6xir8BZdadFsS4NS96XR83215OsblOyMXhAQJWSrqJY56NE4rM PDlkv5rrDs/oIU1zDf1/gb8CTokBUfT0X3/WMNqsepjSLDmMj8HSOYAAWyu/R0kYXeR6 C6Z7tTf4R55UYCObWnDsDgyN2nyiacgB/aTcDCAfCtHHqavXWd1tTDMVClHZBr0JWJ5U j/Ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741470146; x=1742074946; h=mime-version:subject:references:in-reply-to:message-id:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=WylszkhgGppCdQ9fhwqu5okvvRkAZMoS/mkCg8YcmnY=; b=PmjSn91qGESMNYn3dmWb1XGb2s5EiXGjDcsAR72uurBYxlqrHYVMH+tUW8jio1FAR2 Ypq+DRD8YjCc3tBb7BbTAmdPGcpj04X1gf8UK1/5kycOJW97Uz5c6sakFipPui3PEPwm 8UFJPoyj0iE/tQdXBLHMGcb0wYO+gGFZctGtwZ3gfaQ7YQrv5XjpOdy6pdgE2lUyCDGW rx4IVT5cEtv+5cQSiBC2HdbYtWlqxAND51TTVcuy6K1UliNDMGg1/VNzn3tFc6vCdDD2 T6g+3PIlPBqGauP8k0/t8BrWsYKlmUkRbp7fHfygWkBd3iFZ4tzru0a4HETFYirz9wH4 WKBA== X-Gm-Message-State: AOJu0YxBz0opTYZJj1pZBQJR5N6D6/HlTKPboKQIRm0uaRiKAL7ZZcOP Q9omww9LvzeJi5dD0fg56DnzPnJsHj4Vtxj9BcS7VXkuSE/4EWdlLLgzHw== X-Gm-Gg: ASbGncvaY143HG6Am09tPqV6Nh0cncn1ZqhdxjsYf2QrWBvR8SIW8fvO5huhxt9mDqH V9Dqbt4tuPsh9ItjsuVHzZLZ3gbPAw3Om68L1Q+DOwb5puZmNwaE4v+LV+/REiGuAxmB/CQIwit QA076eFLlVviIbxAahgiH3Hf65WbOoZUPER3/ftTXIAJrflbSxQs1XTYfV46qVI2IAHFMoO6XJ9 aEj6tuM1zsvo8JiLWYc2UqRMDEZMrakXZsG7G8jO5570sp8YQf7PfULmJhahTkFx6nBGADsPnc0 0XkgKtPTrUzWVsID3+4LgvehcdGPHAmsxWCBBy9qRFmoK/HZY9KBwS3N89n38UbvOo7elLODk3z yqKgZ++2zIrVemzurEknri6zWrPn8 X-Google-Smtp-Source: AGHT+IFEYBSpLDa7+xa+4iuvwLo2OqtpVMK22Prw3EBPi6q60d+sZmCwXZGK62bS9nkVExi5u8X+Vg== X-Received: by 2002:a05:6402:3495:b0:5e6:20de:f79b with SMTP id 4fb4d7f45d1cf-5e620df0103mr3275741a12.31.1741470146016; Sat, 08 Mar 2025 13:42:26 -0800 (PST) Received: from ?IPv6:::1? (luna-749a6f85f554075d0000f.net.as198747.daniil.it. [2a0e:97c0:38f:0:d570:455f:58f6:a947]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5e5c768ef30sm4424723a12.69.2025.03.08.13.42.24 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 08 Mar 2025 13:42:25 -0800 (PST) Date: Sat, 8 Mar 2025 22:42:21 +0100 (GMT+01:00) To: internals@lists.php.net Message-ID: <676e36e4-0b84-4d8c-b3db-2998831cd79d@gmail.com> In-Reply-To: <77DC5F50-531D-49E8-8BE2-504A19CB5FFD@rwec.co.uk> 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> <8599eb8b-d4a3-4cb8-899a-25b134e0d64d@gmail.com> <74c4c726-63aa-44e0-84c9-840e13a65a4f@gmail.com> <77DC5F50-531D-49E8-8BE2-504A19CB5FFD@rwec.co.uk> Subject: Re: [PHP-DEV] PHP True Async RFC Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_3_176925086.1741470141618" X-Correlation-ID: <676e36e4-0b84-4d8c-b3db-2998831cd79d@gmail.com> From: daniil.gentili@gmail.com (Daniil Gentili) ------=_Part_3_176925086.1741470141618 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit >>> The async block as I'm picturing it has nothing to do with function colouring, it's about the outermost function in an async stack being able to say "make sure the scheduler is started" and "block here until all child fibers are either concluded, detached, or cancelled". >> >> There's no need for such a construct, as the awaitAll function does precisely what you describe, without the need to introduce the concept of a child fiber and the excessive limitation of an async block that severely limits concurrency. > > No, it's not quite that either. The scenario I have in mind is a web / network server spawning a fiber for each request, and wanting to know when everything related to that request is finished, so that it can manage resources. > > If we think of memory management as an analogy, awaitAll would be equivalent to keeping track of all your memory pointers, and making sure to pass them all to free before the end of the request. The construct we're discussing is like a garbage collection checkpoint, that ensures all memory allocated within that request has been freed, even if it wasn't tracked anywhere. > > Written in ugly functions rather than concise and fail-safe syntax, it's something like: > > $managedScope = new ManagedScope; > $previousScope = set_managed_scope( $managedScope ); > > spawn handle_request(); // inside here any number of fibers might be spawned > > $managedScope->awaitAllChildFibers(); // we don't have the list of fibers here, so we can't use a plain awaitAll > > set_managed_scope( $previousScope ); > unset($managedScope); > > > It's certainly worth discussing whether this should be mandatory, default with an easy opt-out, or an equal-footing alternative to go-style unmanaged coroutines. But the idea of automatically cleaning up resources at the end of a task (e.g. an incoming request) is not new, and nor is arranging tasks in a tree structure. I still strongly disagree with the concept of this construct. When we spawn an async function, we care only about its result: all side effects (including spawned fibers I.e. to handle&cache incoming events from sockets, etc..) should not interest us, and eventual cleanup should be handled trasparently by the library we are invoking (i.e. very simply by running awaitAll in a __destruct, according to the library's overall lifetime and logic). I don't think the language should offer a construct that essentially makes sure that an async function or method may not spawn background fibers. This makes no sense, in a way it's offering a tool to meddle with the internal implementation details of any async library, that can prevent libraries from using any background fibers. To make an analogy, it's like saying PHP should have an io {} block, that makes sure all file resources opened within (even internally, 10 stack levels deep into 3 libraries, whose instances are all used after the io {} block) are closed when exiting. Libraries can and should handle cleanup of running fibers by themselves, on their own terms, without externally imposed limitations. > I would also note that the concept of parent and child fibers is also useful for other proposed features, such as cascading cancellations, and having environment-variable style inherited context data. Yes, parenting does make sense for some usecases (indeed I already previously proposed parenting just for cancellations), just not to offer a footgun that explicitly limits concurrency. Regards, Daniil Gentili. ------=_Part_3_176925086.1741470141618 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit
>>> The async block as I'm picturing it has nothing to do with function colouring, it's about the outermost function in an async stack being able to say "make sure the scheduler is started" and "block here until all child fibers are either concluded, detached, or cancelled".
>>
>> There's no need for such a construct, as the awaitAll function does precisely what you describe, without the need to introduce the concept of a child fiber and the excessive limitation of an async block that severely limits concurrency.
>
> No, it's not quite that either. The scenario I have in mind is a web / network server spawning a fiber for each request, and wanting to know when everything related to that request is finished, so that it can manage resources.
>
> If we think of memory management as an analogy, awaitAll would be equivalent to keeping track of all your memory pointers, and making sure to pass them all to free before the end of the request. The construct we're discussing is like a garbage collection checkpoint, that ensures all memory allocated within that request has been freed, even if it wasn't tracked anywhere.
>
> Written in ugly functions rather than concise and fail-safe syntax, it's something like:
>
> $managedScope = new ManagedScope;
> $previousScope = set_managed_scope( $managedScope );
>
> spawn handle_request(); // inside here any number of fibers might be spawned
>
> $managedScope->awaitAllChildFibers(); // we don't have the list of fibers here, so we can't use a plain awaitAll
>
> set_managed_scope( $previousScope );
> unset($managedScope);
>
>
> It's certainly worth discussing whether this should be mandatory, default with an easy opt-out, or an equal-footing alternative to go-style unmanaged coroutines. But the idea of automatically cleaning up resources at the end of a task (e.g. an incoming request) is not new, and nor is arranging tasks in a tree structure.


I still strongly disagree with the concept of this construct.

When we spawn an async function, we care only about its result: all side effects (including spawned fibers I.e. to handle&cache incoming events from sockets, etc..) should not interest us, and eventual cleanup should be handled trasparently by the library we are invoking (i.e. very simply by running awaitAll in a __destruct, according to the library's overall lifetime and logic).

I don't think the language should offer a construct that essentially makes sure that an async function or method may not spawn background fibers.

This makes no sense, in a way it's offering a tool to meddle with the internal implementation details of any async library, that can prevent libraries from using any background fibers.

To make an analogy, it's like saying PHP should have an io {} block, that makes sure all file resources opened within (even internally, 10 stack levels deep into 3 libraries, whose instances are all used after the io {} block) are closed when exiting.

Libraries can and should handle cleanup of running fibers by themselves, on their own terms, without externally imposed limitations.

> I would also note that the concept of parent and child fibers is also useful for other proposed features, such as cascading cancellations, and having environment-variable style inherited context data.

Yes, parenting does make sense for some usecases (indeed I already previously proposed parenting just for cancellations), just not to offer a footgun that explicitly limits concurrency.

Regards,
Daniil Gentili.
------=_Part_3_176925086.1741470141618--