> On Feb 3, 2021, at 8:27 AM, Nikita Popov <nikita....@gmail.com> wrote:
> 
> 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?
> 
> class FiberScheduler {
>    function suspend(Fiber $fiber);
>    function start(Fiber $fiber);
>    function resume(Fiber $fiber);
> }
> 
> 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).
> 
> Regards,
> Nikita
> 

Hi Nikita,

I considered adding start, resume, and throw methods on FiberScheduler as you 
suggested, however I’m 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 – 
suspending {main}, interoperability between libraries using differing 
schedulers, and running schedulers to completion upon script termination.

>>> 
>>> 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’s 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

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to