Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:113555 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 25010 invoked from network); 16 Mar 2021 09:37:08 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 16 Mar 2021 09:37:08 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 4F704180504 for ; Tue, 16 Mar 2021 02:30:52 -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=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-pf1-f176.google.com (mail-pf1-f176.google.com [209.85.210.176]) (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 ; Tue, 16 Mar 2021 02:30:48 -0700 (PDT) Received: by mail-pf1-f176.google.com with SMTP id x7so8397701pfi.7 for ; Tue, 16 Mar 2021 02:30:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=bO0WmsNKN2FkNhFS/Y7s4mXYA9LZ1azVwRI7Y4eLHWQ=; b=T05dbGAW0w8x4SBHgIOU7woBmP5wEXgANmaIf/MRc4hFdAjP48yk8y7PFFcR6S5+YL 1aBRpqfHWZMCJIW9k5/oPqjl9NLjz1GhJowydVS7TPIRE1JMEb7aqTGtjm7OH1KVyXd1 aW7Tc8qlvLyoZ8w2XPxeEpz7lo/+dzzC48OeAXLk9d8apKTbontDBNkopObo2K801SaA CbrMEeYc+M2yxkC/YMADFCVaRtpKRAsytwo1iHP4W1iLxhxpykNYDlp3JnFqLXUGmGYF LvntmQOSKa0/7638XTXlJD8G1RrBqKRf+G60WhtkT8pUQSlCvZzVH3JivETeJ9wBZvc2 4mSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=bO0WmsNKN2FkNhFS/Y7s4mXYA9LZ1azVwRI7Y4eLHWQ=; b=lpaxCCK6x045irQ0M4PWki+aROOaotyM5B4O3qIQusOfaFxtuThkdB++6Rdd7kXyCe InwCkYQErkKIMfyNjSZrF6Do1lvfJLRD3lEjCerVUTKxfB9zRJDsXvEf3Pe6jDd2JkQC MaNYXM/nzcF+N+F1o/75ehw6ONqsDJBD2tG4MKD297Mq8ZbbHbU1L21jgMgnEhOVkk7T tR8ZlO+67hZxJq2whTTfVPwQkApwXU65DmyUK5wcx3X3OOP2+g2GpnBUYg89xC9Hqs2o Afvn6j1FH0smO/nFwSdNAhkXJx8B0IBzMveI8J0Ikb+Mw9dkdrJzYu30hob8I0kF31TV 7NXw== X-Gm-Message-State: AOAM5335dkqRP4bDCAfDjWyDkGIKQREWvJ2VlKJCrKGPouICNo4blN6+ Ua5jGEGDsNITjLftb8roDWk9LGSsoDam201UmtA= X-Google-Smtp-Source: ABdhPJwnzV6S+Wwh/mM+ZCXPBTKpUGZEpDzgat+gYKB5tPKTRgupBH8S4/F4eV08xf+ZNCOWtMXd8jJHkH0X/tb+qXU= X-Received: by 2002:a63:f202:: with SMTP id v2mr3205004pgh.24.1615887047541; Tue, 16 Mar 2021 02:30:47 -0700 (PDT) MIME-Version: 1.0 References: <70951423-5e77-c150-6dce-dd3c62f8dc8b@php.net> <0b994a60-7970-605b-1657-d6ee732690e5@gmx.de> <5C73A1DE-E563-4F69-B8C7-6506F81D7345@trowski.com> In-Reply-To: <5C73A1DE-E563-4F69-B8C7-6506F81D7345@trowski.com> Date: Tue, 16 Mar 2021 09:30:36 +0000 Message-ID: To: Aaron Piotrowski Cc: "Christoph M. Becker" , Michael Wallner , php internals , Derick Rethans Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [VOTE] Fibers From: joshdifabio@gmail.com (Josh Di Fabio) On Fri, Mar 12, 2021 at 10:54 PM Aaron Piotrowski wrote= : > > > > On Mar 12, 2021, at 4:36 PM, Christoph M. Becker wr= ote: > > > > On 12.03.2021 at 23:04, Michael Wallner wrote: > > > >> Thank you, and everyone involved, for your effort. > >> > >> On 08/03/2021 20.40, Aaron Piotrowski wrote: > >>> Greetings everyone! > >>> > >>> The vote has started on the fiber RFC: https://wiki.php.net/rfc/fiber= s > >>> > >>> Voting will run through March 22nd. > >> > >> I voted /no/, because of the dependency on Boost. > >> If my assumptions are wrong, I may reconsider my vote. > > > > Only asm files are used[1], and these can be bundled, so there is no > > dependency on boost or C++ in general. > > > > [1] > > > > -- > > Christoph M. Becker > > > > Hi Mike, Christoph, and Derick, > > To add a bit more information: > > These asm files are part of the low-level boost.context lib, found here: = https://github.com/boostorg/context > > This library has infrequent releases. Some of the files for old architect= ures have not changed in several years. Keeping these files up-to-date will= not be a burden (and I plan to assume this responsibility). > > The Boost license is extremely permissive and approved by the OSI, so the= re is no problem bundling with PHP. > > Hopefully that provides some clarification and you=E2=80=99ll reconsider = your vote Mike. > > Cheers! > Aaron Piotrowski > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > Apologies, this is a long one! This RFC strikes me as being very dangerous. Implicitly allowing code which is synchronous by design to be executed asynchronously seems sure to lead to very subtle, unpredictable, confusing and dangerous bugs. The issue is that executing code asynchronously introduces race conditions and, in code which is synchronous by design, those race conditions will lead to bugs which will never occur during QA or development and will be incredibly hard to identify once they do occur in production. These are the kind of bugs where user sessions get mixed up, the wrong package is installed by a package manager, or an ecommerce website captures the wrong amount of money from a customer's credit card. And developers will have no realistic way of tracking down why these things are happening in real world, multi developer, multi vendor PHP applications. For example, the PHP ecosystem is full of code like this: private function capturePayment() { $paymentRequest =3D preparePaymentRequest($this->currentOrder); $this->paymentGateway->capturePayment($paymentRequest); $this->currentOrder->setTransactionId($paymentRequest->getTransacti= onId()); } In the above code snippet, the developer has relied on the fact that the mutable value $this->currentOrder will be the same before and after the call to $this->capturePayment(), because capturePayment() is synchronous. In all likelihood, the authoring PHP developer is not even familiar with asynchronicity, and the assumption that capturePayment() is synchronous is therefore not even a conscious one. Note that, if capturePayment is executed asynchronously, eventually we will see payments attributed to the wrong orders. Note that, if fibers land, there is no know whether the code above is correct by looking at it in isolation. You can only know that by knowing the environment in which the code is executed, as well as understanding *all of the internals of capturePayment()*, and its dependencies, many of which will probably managed by other developers and will involve a bunch of injected services, many of which will do IO and therefore are candidates for using fibers, directly or indirectly, such as logging, HTTP, and database. The worst characteristics to me are the following: - These race conditions will cause problems so rarely that developers will not even realise that their programs contain dangerous bugs. Code which is not safe to use with fibers will appear to be functional because the happy path will work fine, and so developers will assume it's okay. - Changes very, very far away from your code can cause your code to become unexpectedly asynchronous. Imagine you are using the DynamoDB monolog logger in your application, and that library indirectly uses Guzzle, which gets fiber support. Any place you are logging anything now becomes asynchronous, as well as any code which invokes that code. If you are using some kind of event dispatch pattern then pretty much everything in your program becomes asynchronous. - As a library author, there is no way of knowing how your code is going to be used, and what injected dependencies might use fibers internally. The counter arguments: - "The above code snippet is suboptimal, it shouldn't assume that mutable state remains unchanged following some IO, and the order should be passed in as an arg." -- Whether or not this is true is irrelevant -- developers have relied on the invariants of the PHP language when writing their code, such as synchronous code being synchronous, and this is how lots of code is written in the wild. If this feature lands, that won't change -- very few userland developers will understand this feature, including library authors. - "Fibers should only be enabled in async first programs." and "We could flag that certain libraries are fiber compatible or incompatible." If code appears to work in a fiber environment, people will just use it in a fiber environment, without understanding all of the security issues and horrible bugs they're introducing. This problem should rather be solved at the language level by making async explicit. Consider the following: private async function capturePayment() { $paymentRequest =3D preparePaymentRequest($this->currentOrder); await $this->paymentGateway->capturePayment($paymentRequest); $this->currentOrder->setTransactionId($paymentRequest->getTransacti= onId()); } Looking at the above code, I can see the race condition. It becomes explicit. So I change the code and communicate explicitly via the type system that this function is asynchronous and that my code expects PaymentGateway::capturePayment() to be asynchronous. private async function capturePayment() { $order =3D $this->currentOrder; $paymentRequest =3D preparePaymentRequest($order); await $this->paymentGateway->capturePayment($paymentRequest); $order->setTransactionId($paymentRequest->getTransactionId()); } Regarding PHP's type system not supporting generics, and the associated advantages of this RFC over promises; I agree that this is a problem with promises. But the lack of generics in PHP already means we have no language-level type safety on data structures, which is certainly worse than not having type safety on promises. Psalm et al have provided reasonable solutions to this issue. Sorry for the criticism of the idea -- I've used React and Amp in production on a product which has been in prod for many years -- and I'd be happy to see first class asynchronous support within the language, but I think this RFC would make the language worse, not better. Technically, I'm sure this is great, and I do appreciate that a lot of work has probably been put into this. Thanks