> On Feb 3, 2021, at 8:27 AM, Nikita Popov <[email protected]> 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