-
-
Notifications
You must be signed in to change notification settings - Fork 17
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
await() error in SimpleFiber.php #16
Comments
This code causes
...but only for "github.com", for "google.com" returns proper result.
EDIT: |
@szado Thank you for reporting, this definitely shouldn't have happened! I've tried reproducing this a number of times, but can not reproduce the problem you're seeing on Linux. A segmentation fault is not something that userland PHP code should be able to trigger. There is also no platform-specific code in ReactPHP involved, so I can only suspect this is an issue with the fibers implementation in PHP itself. I don't think this boils down to an issue in ReactPHP itself, so I wonder if we can break this down to a reproducible script that also shows this segmentation fault without ReactPHP? Accordingly, it looks like this should probably be reported upstream in PHP. Can anybody take a look at this and link/report back here? Thank you! |
@clue maybe this code will be helpful: https://github.com/szado/reactphp-connection-pool/blob/master/test.php |
Tested on both Windows and Linux, I didn't notice any difference. The error is present both there and there. Here is my piece of code. I'm trying to wait for a WebSocket response and give it back. As a result, I get an error. If you don't wait for an answer, but just give out any value, everything goes well
|
@szado I can reproduce that error and looking into the exact cause (probably related to |
Ran into the same error. <?php
use React\Promise\Promise;
use React\Promise\PromiseInterface;
use function React\Async\await;
use function React\Promise\resolve;
require_once __DIR__ . '/vendor/autoload.php';
function test(): PromiseInterface {
$resolver = function ($resolve, $reject) {
await(resolve());
$resolve();
};
return new Promise($resolver);
}
await(test());
|
TL;DR You're only having one fiber (the main fiber) running and you want to await for a promise twice, it's simply not possible. |
P.S. Will get you a longer response somewhere between tonight and the end of the weekend. Working on a bunch of examples and a blog post on this. |
@WyriHaximus 👌 It might lead to some unexpected errors when you're using a 3rd party library. Right now the example is pretty useless but replace |
Something like this instead? <?php
use React\Promise\PromiseInterface;
use function React\Async\async;
use function React\Async\await;
use function React\Promise\resolve;
require_once __DIR__ . '/vendor/autoload.php';
function test(): PromiseInterface {
return async(function () {
await(resolve());
});
}
await(test()); |
@bartvanhoutte yes, each async will create a new fiber. |
Just filed #18 that helps with a few cases mentioned in this issue. And intentionally all of them (except the segfault), but I'd have to test that |
Need to translate this into documentation, but write my thoughts and the outlines of our current plan down at: https://blog.wyrihaximus.net/2021/12/async-and-await-at-the-edge-with-reactphp/ |
A valid reason I can think of to call <?php
use React\EventLoop\Loop;
use function React\Async\async;
use function React\Async\await;
require_once __DIR__ . '/vendor/autoload.php';
$timer = Loop::addPeriodicTimer(1, fn() => print 'tick' . PHP_EOL);
$exit = await(async(function () use ($timer) {
Loop::addTimer(10, fn() => Loop::cancelTimer($timer));
return 1;
}));
exit($exit); |
I can no longer reproduce the error from #16 (comment), however there seems to be an issue with timers using <?php
use React\EventLoop\Loop;
use function React\Async\async;
use function React\Async\await;
require_once __DIR__ . '/vendor/autoload.php';
function foo()
{
print __FUNCTION__ . PHP_EOL;
await(async(fn() => null));
}
Loop::addTimer(5, fn() => foo());
The timer is executed twice causing the error. Upon further inspection, it looks like the timer is never removed from the list of timers in |
The same error occurs when an EventLoop is created manually without using Example: <?php
$loop = new \React\EventLoop\ExtEventLoop();
//\React\EventLoop\Loop::set($loop); // solution
$deferred = new \React\Promise\Deferred();
$loop->futureTick(static fn() => $deferred->resolve());
\React\Async\await($deferred->promise());
$loop->run();
Result: After uncommenting |
@bartvanhoutte Very good input, I can see where you're coming from! It looks like most of the issues discussed in this ticket stem from lack of documentation how to use the <?php
use React\EventLoop\Loop;
use function React\Async\async;
use function React\Async\await;
require_once __DIR__ . '/vendor/autoload.php';
function foo()
{
print __FUNCTION__ . PHP_EOL;
- await(async(fn() => null));
+ await(async(fn() => null)()); // or omit as this is a NO-OP
}
- Loop::addTimer(5, fn() => foo());
+ Loop::addTimer(5, async(fn() => foo())); // or Loop::addTimer(5, async('foo')); @Provoker Interesting find! The |
(Great job with Fibers initiative!)
For test purposes I'm refactoring my app with await() function in place of promises-chains. I've got an error:
It occurs when I try to use async() function. It's hard to say how to reproduce this bug. In the same call stack, a few promises before, I use a React\Http\Browser with async() function. If I comment this usage (replace to something like
resolve(new ResultObject())
) - error doesn't occur. If I use Browser with promise-style api, the PHP process ends with error:I'm using the newest versions of all packages, ofc PHP 8.1.
Do you know what can cause these errors?
The text was updated successfully, but these errors were encountered: