Hi, all,
I have updated the RFC https://wiki.php.net/rfc/fiber
changes list:
- introduce the `throw(Exception $exceptin)` API
- record issues discussed
> On Feb 9, 2018, at 08:12, Haitao Lv wrote:
>
>>
>> On Feb 9, 2018, at 06:22, Niklas Keller wrote:
>>
>>>
- How do you determine when a fiber has returned? Looking at the source,
>>> it appears Fiber::status() must be used, comparing against constants.
>>> Separate methods similar to Generator would be better IMO. e.g.:
>>> Fiber::alive(), Fiber::suspended(), Fiber::running()
>>>
>>> Offering methods like Fiber::alive, Fiber::running makes no difference to
>>> check the Fiber::status() return value. This is just a style issue. And as
>>> a language feature,
>>> Fiber only offer the essential API and let other works to the user land.
>>
>>
>> The language should offer a sane API, not the absolute minimum required to
>> work for these things.
>
> The Ruby's Fiber do offer a live? method but does not have a getStatus method.
> The Lua's coroutine only offer a status method.
>
> So do we really need to offer three additional helper method? Or what is your
> advice about these API?
>
>>
- What about throwing exceptions into a fiber?
>>>
>>> Currently does not support throw exception into the fiber. User land code
>>> could check
>>> the value of Fiber::yield and throw exception themselves. The Ruby's Fiber
>>> and Lua's
>>> coroutine also does not support such api as well.
>>
>>
>> And throw the exception where? That means async code with fibers can't
>> really handle errors?
>
> Actually you can transfer any thing to Fiber by the resume method. And you can
> check the return value of Fiber::yield to handle error.
>
> Fiber is designed as a primitive, low level, and lightweight feature. User
> land
> code seldom not need to use them directly in your normal code.
> So the following is not a big problem,
>
> $a = Fiber::yield(...);
> if ($a === false) {
> throw new Exception(...);
> }
>
> And both the Ruby and Lua does not offer such API as well.
>>
>>>
- Using Fiber::resume() to initialize the fiber and resume feels
>>> awkward. Separate methods again would be better here, perhaps
>>> Fiber::init(...$args) and Fiber::resume($send).
>>>
>>> All Fiber created with a suspended status. So make resume to do both the
>>> init and resume
>>> do make sense.
>>>
>>
>> It does't make sense to me. Reading the example in the README and
>> understanding why the first resume() takes two arguments instead of one
>> took me quite some minutes.
>
> This Ruby's Fiber and Lua's coroutine using one resume API to init and resume
> the coroutine. I do not think a dedicate is really required.
>
> The generator cannot be init by it's send method. And if you want to implement
> coroutine feature(without stack) by it, you have to write code
>
> function run() {
>if ($this->beforeFirstYield) {
>$this->beforeFirstYield = false;
>return $this->coroutine->current();
>} else {
>$retval = $this->coroutine->send($this->sendValue);
>$this->sendValue = null;
>return $retval;
>}
> }
>
> It is verbose.
>
> See
> https://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html
>
>>
>>> Please see Ruby Fiber API https://ruby-doc.org/core-2.2.0/Fiber.html.
>>>
- What happens if the sub1() function in the RFC is invoked outside of a
>>> fiber?
>>>
>>> You will get a Fatal Error like
>>> Fatal error: Uncaught Error: Cannot call Fiber::yield out of Fiber
>>>
- I think a keyword here would be beneficial, even if it has a minor BC
>>> impact. Fibers could then be written like generators. `await` or `emit` as
>>> a keyword perhaps? This would be a less verbose API, feel less magical (a
>>> static method call that actually pauses execution feels out of place), and
>>> would allow Fibers to be returned from methods, named functions, etc with
>>> less boilerplate.
>>>
>>> Wishing this to be accepted by the community in the PHP 7.3, so no keyword
>>> is accepted.
>>> And if the community cannot accept, the Fiber can be still distributed as
>>> a standalone
>>> extension. So we cannot depend on a new keyword.
>>
>>
>> Right, if it's a standalone extension it can't use a new keyword, but as a
>> language feature it totally can.
>
> In my opinion, using a keyword or call a method is just a coding style
> problem.
> Introducing a new keyword does not offer any benefit by makes a minor BC.
>
> Both Ruby's Fiber and Lua's coroutine does not required a dedicate keyword.
>
>> Looking at the current README, there are two issues that must be completely
>> solved IMO before accepting this:
>>
>>> Each Fiber has a separate 4k stack. You can use the fiber.stack_size ini
>> option to change the default stack size. You can also use the second
>> argument of Fiber::__construct to set the stack size on fly.
>>
>> Resizing