Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:113632 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 21925 invoked from network); 19 Mar 2021 20:00:36 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 19 Mar 2021 20:00:36 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 21F821804DF for ; Fri, 19 Mar 2021 12:55:11 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.6 required=5.0 tests=BAYES_00,BODY_8BITS, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, NICE_REPLY_A,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Fri, 19 Mar 2021 12:55:10 -0700 (PDT) Received: by mail-ej1-f49.google.com with SMTP id a7so11599103ejs.3 for ; Fri, 19 Mar 2021 12:55:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding:content-language; bh=wLYVStFN8d93tWzR4a9r1bsx/vaoexZrc3aIiPKpn8U=; b=dqwBJy9m2nJSokHpkKwNrMK/xvyNAzuDIa38kkSpQQueqmxw5QCSbbxi/kfOd/HqvM nIY+hk7ZlF22xDflDya4omtoh822vjjvhK1+/1Tu+hBb+8L9O4WOStW69eHb9o+BCn+/ xQ970jXfw7IqBzTPNxHhleXSBdJJd3shYD4w1Sjo9X02NJ32C8CUSvf5sweMDOG1qFEx /zckXbjASEVNx4TiBRj8gw4pQFpebZw4EQc9CBv8BGrZ22f+TivKa8hmBvtKMwMS/l0V RaMl8MjqViVRX058Zga1fBGaTosjFH9Ne9eovS1sW+3//jKUC0OgTBN04WApFkOKJ6r5 8EWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=wLYVStFN8d93tWzR4a9r1bsx/vaoexZrc3aIiPKpn8U=; b=JyB+HMZwT3SCDPEz6u8YJ1WMJ88dQ7RH2LaIB8G99ZGOAH0qIS60mTbIDfWL8I8vR9 7q5ix42jo4FNjRATNghn0ndZaU6W5VFxHsj4gCAsmS6WWbRsSw7bWEyCB77F4GYY4rF/ samzVOC8r9daH7hgrWVLDco0wEcluelnIfezXdIjnzXrVmt9mO1oZWZdUjYBeArT7gly 7QeKPQOhukE7srmoNYhtcHy2zY+0fK21LTPL6BSjeUABHQFfdXhLbhLXRu486GZip69Q t2fdLn6E21RUrItt8GxNv6rLPCGUysKQvfMrtsHRNKnBJgaQ4RnG2jOomcA6GD3vCLwm 8lTg== X-Gm-Message-State: AOAM530MQzu62qr7U9RYIJ4co49yf5D6sBF+NTIbF0eCwl1CjGvgjwAV mcFi1HefoVCAd3zjT+UDrI/gN70tq60= X-Google-Smtp-Source: ABdhPJwBo6kMZGKlYadnr545jeIqaVgHRfbQmuF8xlOIaWmy20Pf1iXG2PCajRbuAtAcrxRqFRzT1A== X-Received: by 2002:a17:906:1113:: with SMTP id h19mr6221066eja.478.1616183708645; Fri, 19 Mar 2021 12:55:08 -0700 (PDT) Received: from [192.168.0.22] (cpc104104-brig22-2-0-cust548.3-3.cable.virginm.net. [82.10.58.37]) by smtp.googlemail.com with ESMTPSA id hd37sm4059283ejc.114.2021.03.19.12.55.07 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 19 Mar 2021 12:55:07 -0700 (PDT) To: internals@lists.php.net References: <70951423-5e77-c150-6dce-dd3c62f8dc8b@php.net> <0b994a60-7970-605b-1657-d6ee732690e5@gmx.de> <5C73A1DE-E563-4F69-B8C7-6506F81D7345@trowski.com> Message-ID: Date: Fri, 19 Mar 2021 19:55:07 +0000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.8.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-GB Subject: Re: [PHP-DEV] [VOTE] Fibers From: rowan.collins@gmail.com (Rowan Tommins) On 18/03/2021 09:20, Josh Di Fabio wrote: > "If you want to enable fibers in your application, you must be > confident about the implementation details of all of the code in your > application, including that of your dependencies, which are written > and maintained by other developers." > > I don't have anything to add to my previous point in that I disagree > that this is practical. While I agree that this is extremely difficult, and slows adoption of asynchronous technologies, I think the challenge is not identifying asynchronous code, it's identifying shared state. In your example, you show code that was written to use shared state unwittingly calling code that was written to be asynchronous:     private function capturePayment()     {         $paymentRequest = preparePaymentRequest($this->currentOrder); $this->paymentGateway->capturePayment($paymentRequest); $this->currentOrder->setTransactionId($paymentRequest->getTransactionId());     } However, the same problem exists the other way around - code written to be asynchronous unwittingly calling code written to use shared state:     private async function capturePayment()     {         $paymentRequest = $this->someDependency->preparePaymentRequest();         await $this->paymentGateway->capturePayment($paymentRequest); $this->someDependency->setTransactionId($paymentRequest->getTransactionId());     } This all looks fine - but what if someDependency is actually calling into a library which stores the current order in a static variable? Now you have exactly the same race condition for the opposite reason. And the solution is the same: carefully vet all your dependencies. I can think of a few ways of solving this: 1) Require all the code to be synchronous. This is easy in PHP, even if Fibers are supported: just don't run in an asynchronous framework. 2) Require most of the code to be synchronous. This is the common approach of labelling functions as "async" or converting return values to Generators or Promises. The big disadvantage is that it requires rewriting a lot of code that doesn't care one way or the other if it's called synchronously. 3) Require all the code to be free of shared state. This is ultimately the only way you'll get the full advantage of asynchronous code. 4) Require most of the code to be free of shared state. Having some primitives in the language to mark out code that definitely *can't* be asynchronous would probably be useful. Perhaps you could mark a function as "no-interrupt"; this could then be used as a wrapper when calling into a library you know or suspect of using state in unsafe ways. > Perhaps we could rather make fibers*opt in* at the*callsite* > (similar to goroutine calls) in order to prevent functions > unexpectedly being executed asynchronously due to faraway changes. > This would be safe and predictable while also avoiding the "What color > is your function" problem. Although this would avoid keeping both synchronous and asynchronous versions of the same function, it would require adding that keyword to every single function call, just in case somewhere inside it wants to take advantage of your asynchronous environment. From my limited understanding, goroutines are a completely different concept. Saying "go someFunction()" in Go immediately starts a new thread-like thing, and doesn't return anything. The runtime manages the scheduling of the thread, but if you want to get any data out of the goroutine, you have to pass it explicitly, e.g. via a channel. Regards, -- Rowan Tommins [IMSoP]