-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Implement Fibers #6875
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Fibers #6875
Conversation
2d09d0d
to
69e1cad
Compare
|
Fatal error: Uncaught Exception: test in %sfailing-fiber.php:%d | ||
Stack trace: | ||
#0 [internal function]: {closure}() | ||
#1 {main} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, this trace is not super clear to me. Does {main}
here refer to the top of the fiber, and the caller of resume() is not present at all?
I feel like at the very least there should be an indication that we're inside a fiber here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way we could change [internal function]
to something like [fiber]
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One suggestion I have is swapping {main}
to {fiber}
in the exception backtrace: trowski@8265319
I attempted to save a pointer the call stack invoking start, but a fiber is able to long outlast the stack that may have started it. It's also undesirable to swap the stack trace on each resume, as this will drop the backtrace context in the fiber, which leads to the terrible backtraces we often had with Generators in Amp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One suggestion I have is swapping {main} to {fiber} in the exception backtrace: trowski/php-src@8265319
Adding a bool for this seems really ad-hoc ... would it be valuable for something if the exception contains a reference to the containing Fiber object outright?
I attempted to save a pointer the call stack invoking start, but a fiber is able to long outlast the stack that may have started it. It's also undesirable to swap the stack trace on each resume, as this will drop the backtrace context in the fiber, which leads to the terrible backtraces we often had with Generators in Amp.
Not sure I follow. To be clear, what I would expect is the backtrace at the point of resume, not at point of start. For generators, this is implemented with a dummy frame that gets resolved when the backtrace is actually fetched. Why are the resulting backtraces "terrible"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nikic Including resume()
doesn't really make sense, because you want the complete fiber stack there, where resume()
would be somewhere in between. But having {main}
there is really weird, I guess it should be {fiber}
.
|
||
public function isRunning(): bool {} | ||
|
||
public function isTerminated(): bool {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need these methods on ReflectionFiber if they're already available on Fiber?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The RFC did include them, but you can just as easily do $reflection->getFiber()->isSuspended()
. I'm fine with removing them, we can always add them back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we instead skip ReflectionFiber
entirely and add the methods to Fiber
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That might make sense. The current split is basically just "these are only used for debugging"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, basically.
Fixed in f062904. |
The observer functionality should be tested via zend_test. |
I moved the observer functionality to zend_observer and added tests in zend_test. |
e38740f
to
f96610f
Compare
Can you double check this is fixed now? I'm not seeing it anymore, but I want to be sure you're not either. |
Yeah, this works fine now. |
This will need a small rebase due to some conflicting error handling changes I've made. |
Improved readability of the results of status tests.
This is using boost context 1.76. However, I'm only bundling the files that can be resolved by configure. I added the s390x files, looks to work fine. |
While reviewing the observers handling, I've noticed that first_observed_frame and current_observed_frame are unfortunately global, as well as zend_observer_fcall_end_all only affecting a single fiber, instead of them all. In PHP 8.0 there's a guarantee that all begun observer callback also will have the end callback called. With fibers this seems to not be true in a bailout case at least. |
Can we kill zend_observer_fcall_end_all() and let the extension deal with it? |
I'm pretty unsure about this. I guess an extension can keep track of all currently begun observers, prepend a custom internal callback to BG(user_shutdown_function_names) and then cleanup itself. This most probably is the least error prone way. This first_observed_frame and current_observed_frame seems really susceptible for being invalid... |
Not sure I understand. It is important to the design of observers that each extension doesn't have to handle weird cases where they have to end things manually. Are you asking to move this out of the engine and into every extension? If so, I must object. These edge cases change over time, as the new fibers case show. We didn't even make it one minor version without a new edge case! |
I would expect this to be a lot easier to handle for an extension, because it knows which open internal state it has that needs to be closed. It doesn't need to integrate with any of the actual observer infrastructure. I grudgingly accepted this hack back then on the premise that it at least won't hurt, but that clearly hasn't held up. If there is no robust implementation of this functionality (and no, @bwoebi's recent commit just adds one more hack on top of the hack) then I'm not willing to provide it at all. |
Zooming out, the only robust solution I see is to sunset zend_bailout across the board. |
Yep, my fix is just for an actual issue people are facing, I'm definitely not happy with this as a long term solution. @SammyK I really don't know how doable sunsetting zend_bailout is ... I mean, any OOM will trigger a bailout for example, but shutdown sequence shall still happen. |
What is blocking OOM from doing a clean shutdown similar to unwind exit? |
For PHP 8.1 I think we should try to play whack-a-mole with the issues and keep |
I like this. FWIW I started working on a big "sunsetting zend_bailout" doc earlier this year but lost steam on it. Maybe when winter hits I'll get bored and start working on it again. 😄 |
OOMs can happen in midst of any function basically, and all our code assumes that emalloc() will return a valid chunk of memory. So basically everything would horribly break if we were to return an invalid pointer (incl. NULL). |
Bah. Good point. We can revisit this issue while trying to find a path to sunset zend_bailout a bit later. |
> Support for Fibers has been added. I've gone through all PRs I could find related to this and these were the only classes I could find to account for. Includes unit tests. Refs: * https://www.php.net/manual/en/migration81.new-features.php#migration81.new-features.core.fibers * https://wiki.php.net/rfc/fibers * https://www.php.net/manual/en/language.fibers.php * php/php-src#6875 * php/php-src@c276c16
> Support for Fibers has been added. I've gone through all PRs I could find related to this and this was the only in directive I could find to account for. Includes unit tests. Refs: * https://www.php.net/manual/en/migration81.new-features.php#migration81.new-features.core.fibers * https://wiki.php.net/rfc/fibers * https://www.php.net/manual/en/language.fibers.php * php/php-src#6875 * php/php-src@c276c16
> Added `CURLStringFile`, which can be used to post a file from a string rather than a file Refs: * https://github.com/php/php-src/blob/f67986a9218f4889d9352a87c29337a5b6eaa4bd/UPGRADING#L231-L235 * php/php-src#6456 * php/php-src@e727919 As part of the Fibers RFC/PR, the Reflection extension also received a new class. * https://wiki.php.net/rfc/fibers * php/php-src#6875 * php/php-src@c276c16 Note: I've not listed the `Fiber` and `FiberError` classes as those could be considered covered via the mention of Fibers on the "New Features" page, though happy to update the commit if so desired.
> Added `CURLStringFile`, which can be used to post a file from a string rather than a file Refs: * https://github.com/php/php-src/blob/f67986a9218f4889d9352a87c29337a5b6eaa4bd/UPGRADING#L231-L235 * php/php-src#6456 * php/php-src@e727919 As part of the Fibers RFC/PR, the Reflection extension also received a new class. * https://wiki.php.net/rfc/fibers * php/php-src#6875 * php/php-src@c276c16 Note: I've not listed the `Fiber` and `FiberError` classes as those could be considered covered via the mention of Fibers on the "New Features" page, though happy to update the commit if so desired. Co-authored-by: jrfnl <jrfnl@users.noreply.github.com> Closes GH-1447.
> Added `CURLStringFile`, which can be used to post a file from a string rather than a file Refs: * https://github.com/php/php-src/blob/f67986a9218f4889d9352a87c29337a5b6eaa4bd/UPGRADING#L231-L235 * php/php-src#6456 * php/php-src@e727919 As part of the Fibers RFC/PR, the Reflection extension also received a new class. * https://wiki.php.net/rfc/fibers * php/php-src#6875 * php/php-src@c276c16 Note: I've not listed the `Fiber` and `FiberError` classes as those could be considered covered via the mention of Fibers on the "New Features" page, though happy to update the commit if so desired. Co-authored-by: jrfnl <jrfnl@users.noreply.github.com> Closes phpGH-1447.
Implementation of the Fibers RFC.