Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126626 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 426A61A00BC for ; Fri, 7 Mar 2025 22:02:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1741384776; bh=AAloHsmlZoo2VS3FYQu25KTClsMdjrhES6G9jGHeqx4=; h=Date:From:To:In-Reply-To:References:Subject:From; b=MSeUdfeH3pnOj5r6A/mH5OCHTQh6XibWAl11k/+u5HQY59vXm6v+FMOw+y43NHCKI 8PbFjf44bvUaNImndYthofqWw9CBYJHppGgJ8D22FSWdNe+Co+e2Sf0a3neiwCHPkM 2rLxgTXEkb3McwO1n/fDYMQA3ZpiX0ZyUkWcKe6w4OlbZ+MCvfU/5hGV/DMU2+SUaU 0rWRXip8GcPdmWeXR5F0Kricl7YrJahxmoa6PsaarWve1cXYEBkI0mJRLLfv9HkLBO B7VzjLFcPrVpsXWB/7LhiyjX8G9OooP/Hw6mgJdysU15nmXt7Ap55vhRsN33blO5Z0 J+7HPp1EJvmyg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 4BA801801D4 for ; Fri, 7 Mar 2025 21:59:35 +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.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,RCVD_IN_DNSWL_LOW, SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from fout-b7-smtp.messagingengine.com (fout-b7-smtp.messagingengine.com [202.12.124.150]) (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 Mar 2025 21:59:34 +0000 (UTC) Received: from phl-compute-04.internal (phl-compute-04.phl.internal [10.202.2.44]) by mailfout.stl.internal (Postfix) with ESMTP id E51781140161 for ; Fri, 7 Mar 2025 17:02:09 -0500 (EST) Received: from phl-imap-06 ([10.202.2.83]) by phl-compute-04.internal (MEProxy); Fri, 07 Mar 2025 17:02:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to; s=fm1; t=1741384929; x=1741471329; bh=11CK2GFZSQMnlaaehfz/t ULq2GbtnerrX8i9DDF87mA=; b=E7nOhnz5VlMEjUBRBbJFMnQWYWnYO+4QfvkBW EnEKIV9m7ZrKIPawloTmWtuFulsKySG32xmu4r7JHYo+1XO2Shq8F2XokDZI4ce1 DzvC3u86umtvt8/NZa/9Ueu5WBgnVrX9HoLK7q341ldnuhMn/VfM3ttEpvzZ2x18 nGoPQTHeSEKPxQtZSUM9Z7a8m18udk5/1KOquooYIv463BZl7DHut2mwXPG7sf+K +XMJEGbBo/oZE5m7VSSW6SymRaPMx+lv8oMVm3RD53F57qYVrSjWVzIzq5eoUAis tzmNrEgF824GprfDWmYxus7+mBZ4uhAvW7hFLqC3hs2oBPCUg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1741384929; x=1741471329; bh=1 1CK2GFZSQMnlaaehfz/tULq2GbtnerrX8i9DDF87mA=; b=tP0epcf/ezioICrKc XM+HD51EmHCQZ9sL1WmI9xQfF4KOyZLTZfHcLQ8L8RxORiSFfh+SoZU3FJuAc3U1 KE3wi+B0Z0B8tAhQPcudUYpP8cjB0UwvQEjrloo6fJK8D669G3ngRFIka2pvKU9R tOWiiZqPL/fR04GvJtExdzebt8/hbaAi1YFFWyMqrZQkMpaUzn5cJMhHB9r5sBsK XwW92Lhnfa2JpkCCNAa9PyemrRs/g+cDZexBTGfGLZgs5eQUeBRLKtvqGUIeFDRq g5uRmHcbyAvuVBCtQDPxSb4PiiVa1554pC8b3kTcB4hWOTt8Cni+ecOtCHLF0XlS DeP4g== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdduuddukedtucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggv pdfurfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpih gvnhhtshculddquddttddmnecujfgurhepofggfffhvffkjghfufgtgfesthejredtredt tdenucfhrhhomhepfdfnrghrrhihucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrh hfihgvlhguthgvtghhrdgtohhmqeenucggtffrrghtthgvrhhnpedugedvlefgueegheef jeetffduveeltefhfeegjeffffelgedttdevkeegkedugfenucevlhhushhtvghrufhiii gvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehlrghrrhihsehgrghrfhhivghlught vggthhdrtghomhdpnhgspghrtghpthhtohepuddpmhhouggvpehsmhhtphhouhhtpdhrtg hpthhtohepihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 7070D29C006F; Fri, 7 Mar 2025 17:02:09 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Fri, 07 Mar 2025 16:01:47 -0600 To: "php internals" Message-ID: <48d66433-3ae9-4895-8361-7c81a0a3670d@app.fastmail.com> In-Reply-To: <07973EAE-2D83-47A8-8FA0-84286C77C02B@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> Subject: Re: [PHP-DEV] PHP True Async RFC Content-Type: text/plain Content-Transfer-Encoding: 7bit From: larry@garfieldtech.com ("Larry Garfield") On Fri, Mar 7, 2025, at 3:39 AM, Rowan Tommins [IMSoP] wrote: > On 6 March 2025 19:07:34 GMT, Larry Garfield wrote: >>It is literally the same argument for "pass the DB connection into the constructor, don't call a static method to get it" or "pass in the current user object to the method, don't call a global function to get it." These are decades-old discussions with known solved problems, which all boil down to "pass things explicitly." > > I think the counterargument to this is that you wouldn't inject a > service that implemented a while loop, or if statement. I'm not even > sure what mocking a control flow primitive would mean. > > Similarly, we don't pass around objects representing the "try context" > so that we can call "throw"as a method on them. I'm not aware of > anybody complaining that they can't mock the throw statement as a > consequence, or wanting to work with multiple "try contexts" at once > and choose which one to throw into. > > A lexically scoped async{} statement feels like it could work > similarly: the language primitive for "run this code in a new fiber" > (and I think it should be a primitive, not a function or method) would > look up the stack for an open async{} block, and that would be the > "nursery" of the new fiber. [You may not like that name, but it's a lot > less ambiguous than "context", which is being used for at least two > different things in this discussion.] > > Arguably this is even needed to be "correct by construction" - if the > user can pass around nurseries, they can create a child fiber that > outlives its parent, or extend the lifetime of one nursery by storing a > reference to it in a fiber owned by a different nursery. If all they > can do is spawn a fiber in the currently active nursery, the child's > lifetime guaranteed to be no longer than its parent, and that lifetime > is defined rigidly in the source code. > > Rowan Tommins > [IMSoP] Since I think better in code, if using try-catch as a model, that would lead to something like: function foo(int $x): int { // if foo() is called inside an async block, this is non-blocking. // if it's called outside an async block, it's blocking. syslog(__FUNCTION__); return 1; } function bar(int $x): int { return $x + 1; // Just a boring function like always. } function baz(int $x): int { // Because this is called here, baz() MUST only be called from // inside a nested async block. Doing otherwise cause a fatal at runtime. spawn foo($x); } async { // Starts a nursery $res1 = spawn foo(5); // Spawns new Fiber that runs foo(). $res2 = spawn bar(3); // A second fiber. $res3 = spawn baz(3); // A Third fiber. // merge results somehow return $combinedResult; } // We block here until everything spawned inside this async block finishes. spawn bar(3); // This is called outside of an async() block, so it just crashes the program (like an uncaught exception). Is that what you're suggesting? If so, I'd have to think it through a bit more to see what guarantees that does[n't] provide. It might work. (I deliberately used spawn instead of "await" to avoid the mental association with JS async/await.) My biggest issue is that this is starting to feel like colored functions, even if partially transparent. --- Another point worth mentioning: I get the impression that there are two very different mental models of when/why one would use async that are floating around in this thread, which lead to two different sets of conclusions. 1. Async in the small: Like the reporting example, "fan out" a set of tasks, and bring them back together quickly before continuing in an otherwise mostly sync PHP-FPM process. All the data is still part of one user request, so we still have "shared nothing." 2. Async in the large: A long running server like Node.js, ReactPHP, etc. Multiplexing several user requests into one OS process via async on the IO points. Basically the entire application has a giant async {} wrapped around it. Neither of these is a bad use case, and they're not mutually exclusive, but they do lead to different priorities. I freely admit my bias is towards Type 1, while it sounds like Edmond is coming from a Type 2 perspective. Not a criticism, just flagging it as something that we should be aware of. --Larry Garfield