Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:113070 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 59603 invoked from network); 3 Feb 2021 19:13:00 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 3 Feb 2021 19:13:00 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id A71B0180089 for ; Wed, 3 Feb 2021 10:56:32 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mercury.negativeion.net (mercury.negativeion.net [199.38.81.6]) by php-smtp4.php.net (Postfix) with ESMTP for ; Wed, 3 Feb 2021 10:56:32 -0800 (PST) Received: from localhost (localhost [127.0.0.1]) by mercury.negativeion.net (Postfix) with ESMTP id D01C720C4A9975; Wed, 3 Feb 2021 13:56:31 -0500 (EST) Received: from mercury.negativeion.net ([127.0.0.1]) by localhost (mercury.negativeion.net [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id CfPffRbcw9d3; Wed, 3 Feb 2021 13:56:31 -0500 (EST) Received: from [10.0.1.101] (unknown [173.225.146.47]) by mercury.negativeion.net (Postfix) with ESMTPSA id 1064120C4A9969; Wed, 3 Feb 2021 13:56:31 -0500 (EST) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.1\)) In-Reply-To: Date: Wed, 3 Feb 2021 12:56:30 -0600 Cc: Niklas Keller , php internals Content-Transfer-Encoding: quoted-printable Message-ID: <2099AE56-3C65-45F3-B107-F09124DE4D58@trowski.com> References: To: Nikita Popov X-Mailer: Apple Mail (2.3608.120.23.2.1) Subject: Re: [PHP-DEV] [RFC] Fibers From: aaron@trowski.com (Aaron Piotrowski) > On Feb 3, 2021, at 8:27 AM, Nikita Popov wrote: >=20 > If you stick to the FiberScheduler concept, then you might want to = consider > inverting the API. Right now you're basically using a standard Fiber = API, > with the difference that suspend() accepts a FiberScheduler, which is > unintuitive to me. If Fibers require a scheduler anyway, why are the > suspend and resume methods not on the scheduler? >=20 > class FiberScheduler { > function suspend(Fiber $fiber); > function start(Fiber $fiber); > function resume(Fiber $fiber); > } >=20 > Both methods are bound to the scheduler in that "suspend" suspends = back to > a certain scheduler, while "resume" resumes a fiber such that it will > return back to this scheduler on termination. This also makes it more > obvious that, for example, it's not possible to just do a = "$fiber->start()" > without having created a scheduler first (though it does not make it > obvious that the call has to be from within the scheduler). >=20 > Regards, > Nikita >=20 Hi Nikita, I considered adding start, resume, and throw methods on FiberScheduler = as you suggested, however I=E2=80=99m not sure it would serve to make = the API clearer. The callback (function, method, etc.) that is used to = create the instance of FiberScheduler does not immediately have a = reference to the created FiberScheduler object, so using the object = within that callback would be awkward. One solution would be a = `FiberScheduler::this()` method, but I think that adds complexity for = not much gain. `FiberScheduler::this()->resume($fiber, $value)` is, in = my opinion, less intuitive than `$fiber->resume($value)`. Either would = have to be called within the callback provided to the FiberScheduler = constructor. Niklas otherwise outlined the reasons to have FiberScheduler a unique = fiber =E2=80=93 suspending {main}, interoperability between libraries = using differing schedulers, and running schedulers to completion upon = script termination. >>>=20 >>> What's not clear to me is why the scheduling fiber needs to be >>> distinguished from other fibers. If we want to stick with the = general >>> approach, why is Fiber::suspend($scheduler) not = Fiber::transferTo($fiber), >>> where $fiber would be the fiber serving as scheduler (but otherwise = a >>> normal Fiber)? I would expect that context-switching between = arbitrary >>> fibers would be both most expressive, and make for the smallest = interface. When starting or resuming a fiber, the current execution point in the = current fiber is stored as the point to jump to when the = starting/resuming fiber suspends or terminates. Fibers must therefore be = only pushed or popped from a stack, you cannot switch to an already = running fiber, as another fiber higher in the stack would no longer = return to the correct execution point when suspended or terminated. Since FiberScheduler internally is just another fiber, there=E2=80=99s = nothing really special done to switch to a fiber scheduler. Requiring = suspending to a scheduler rather than an arbitrary fiber prevents users = from attempting to switch to an already running fiber. Cheers, Aaron Piotrowski