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

Promise\wait together with Promise\rethrow #236

Closed
prolic opened this Issue Sep 9, 2018 · 14 comments

Comments

2 participants
@prolic
Contributor

prolic commented Sep 9, 2018

(copied from irc)

hi folks
php: src/unix/core.c:896: uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed.
what does that tell me?

this happened to me once I added some new tests today
but it appeared on old tests
so I encounter this only when running the whole test-suite
I switched to EV and the problem disappeared
seems to be a bug in UV ?

I wrote 2 new test classes today, one results in to uv error above, which I can prevent by switching to ev
the second one makes a bunch of old tests red, when I start the whole test-suite, but they will all be green again, when I exclude this one
so weird

mmh... seems to have something to do with using wait(call(...)) within the tests, and inside the lib I do Promise\rethrow($subscription->start()); somewhere
when I don't to the rethrow thing, then the other tests are green again

I can make the tests pass with a different Promise\wait implementation
check this out please

function wait($promise) {
        if (!$promise instanceof Promise) {
            if ($promise instanceof ReactPromise) {
                $promise = adapt($promise);
            } else {
                throw createTypeError([Promise::class, ReactPromise::class], $promise);
            }
        }

        $resolved = false;
        $wait = true;
        $exception = null;
        $value = null;

        $promise->onResolve(function ($e, $v) use (&$resolved, &$value, &$exception, &$wait) {
            $resolved = true;
            $exception = $e;
            $value = $v;
            $wait = false;
            Loop::stop();
        });

        while($wait) {
            Loop::run();
        }

        if ($exception) {
            throw $exception;
        }

        return $value;
    }

but uv still is a problem

@kelunik

This comment has been minimized.

Show comment
Hide comment
@kelunik

kelunik Sep 9, 2018

Member

php: src/unix/core.c:896: uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed.

This happens if you have two watchers on the same FD, which should only happen if there's either a bug in the UvDriver or you open STDIN / STDOUT / STDERR manually.

Your different implementation indicates that the event loop exits somewhere where it shouldn't, so it's probably just hiding the bug instead of fixing it.

Member

kelunik commented Sep 9, 2018

php: src/unix/core.c:896: uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed.

This happens if you have two watchers on the same FD, which should only happen if there's either a bug in the UvDriver or you open STDIN / STDOUT / STDERR manually.

Your different implementation indicates that the event loop exits somewhere where it shouldn't, so it's probably just hiding the bug instead of fixing it.

@prolic

This comment has been minimized.

Show comment
Hide comment
@prolic

prolic Sep 9, 2018

Contributor
Contributor

prolic commented Sep 9, 2018

@prolic

This comment has been minimized.

Show comment
Hide comment
@prolic

prolic Sep 9, 2018

Contributor

I did some output using STDOUT in the unit tests and remove it. Now this happens:

ERRORS!
Tests: 118, Assertions: 240, Errors: 1.
php: src/unix/core.c:896: uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed.
[1]    22191 abort (core dumped)  ./vendor/bin/phpunit --stop-on-failure

So I guess here this is because of PHPUnit writing to STDOUT.

Your different implementation indicates that the event loop exits somewhere where it shouldn't.

What does that mean? I tried to look for Loop:run() everywhere, no match. (It's only called by wait in the tests). Can you give me an example of an event loop that exists somewhere where it shouldn't and causing trouble?

Contributor

prolic commented Sep 9, 2018

I did some output using STDOUT in the unit tests and remove it. Now this happens:

ERRORS!
Tests: 118, Assertions: 240, Errors: 1.
php: src/unix/core.c:896: uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed.
[1]    22191 abort (core dumped)  ./vendor/bin/phpunit --stop-on-failure

So I guess here this is because of PHPUnit writing to STDOUT.

Your different implementation indicates that the event loop exits somewhere where it shouldn't.

What does that mean? I tried to look for Loop:run() everywhere, no match. (It's only called by wait in the tests). Can you give me an example of an event loop that exists somewhere where it shouldn't and causing trouble?

@prolic

This comment has been minimized.

Show comment
Hide comment
@prolic

prolic Sep 9, 2018

Contributor

Loop stopped without resolving the promise - happening only when running complete test suite, all tests pass when I check every single test class. How can I find out why?

Contributor

prolic commented Sep 9, 2018

Loop stopped without resolving the promise - happening only when running complete test suite, all tests pass when I check every single test class. How can I find out why?

@prolic

This comment has been minimized.

Show comment
Hide comment
@prolic

prolic Sep 9, 2018

Contributor

After excluding a bunch of tests I could achieve this:

OK (139 tests, 286 assertions)
php: src/unix/core.c:896: uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed.
[1]    23913 abort (core dumped)  ./vendor/bin/phpunit --stop-on-failure --exclude-group=by

No STDIN, STDOUT, STDERR, echo, var_dump or print is used in src and tests directory. Only one outputting is PHPUnit (usually this should happen before and after the wait() call inside tests).

Contributor

prolic commented Sep 9, 2018

After excluding a bunch of tests I could achieve this:

OK (139 tests, 286 assertions)
php: src/unix/core.c:896: uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed.
[1]    23913 abort (core dumped)  ./vendor/bin/phpunit --stop-on-failure --exclude-group=by

No STDIN, STDOUT, STDERR, echo, var_dump or print is used in src and tests directory. Only one outputting is PHPUnit (usually this should happen before and after the wait() call inside tests).

@kelunik

This comment has been minimized.

Show comment
Hide comment
@kelunik

kelunik Sep 11, 2018

Member

Maybe just create your PR so I can have a look?

Member

kelunik commented Sep 11, 2018

Maybe just create your PR so I can have a look?

@prolic

This comment has been minimized.

Show comment
Hide comment
@prolic

prolic Sep 12, 2018

Contributor

what should I PR? my custom wait() function or the project that currently runs into issues?

Contributor

prolic commented Sep 12, 2018

what should I PR? my custom wait() function or the project that currently runs into issues?

@kelunik

This comment has been minimized.

Show comment
Hide comment
@kelunik

kelunik Sep 12, 2018

Member

Oh, it's in another project, I thought I had written some additional tests for Amp itself. Do you have a link to the tests either way?

Member

kelunik commented Sep 12, 2018

Oh, it's in another project, I thought I had written some additional tests for Amp itself. Do you have a link to the tests either way?

@prolic

This comment has been minimized.

Show comment
Hide comment
@prolic

prolic Sep 12, 2018

Contributor

Here is the project:
https://github.com/prooph/event-store-client/

this is the last working commit: prooph/event-store-client@0c6f3fc

master is now +2 more commits and failing on travis suddenly (not the new tests added in those 2 commits, but older one): https://travis-ci.org/prooph/event-store-client/builds/426297716

When I replace uv with ev, I don't get the uv__io_stop: Assertionloop->watchers[w->fd] == w` problem, with my custom wait method then all tests pass again.

Contributor

prolic commented Sep 12, 2018

Here is the project:
https://github.com/prooph/event-store-client/

this is the last working commit: prooph/event-store-client@0c6f3fc

master is now +2 more commits and failing on travis suddenly (not the new tests added in those 2 commits, but older one): https://travis-ci.org/prooph/event-store-client/builds/426297716

When I replace uv with ev, I don't get the uv__io_stop: Assertionloop->watchers[w->fd] == w` problem, with my custom wait method then all tests pass again.

@prolic

This comment has been minimized.

Show comment
Hide comment
@prolic

prolic Sep 12, 2018

Contributor

By the way, the event-store-client comes with a logger, when I turn on verbose mode and enable consoler logger (using Amp\Log\ConsoleFormatter and Amp\Log\StreamHandler) I can see a bunch of output during the tests. But then AFTER I see PHPUnit output with X tests, Y assertions, Z errors, there comes additional output from that logger.

Something like "connection was closed because of X" - is that expected for the StreamHandler?

Contributor

prolic commented Sep 12, 2018

By the way, the event-store-client comes with a logger, when I turn on verbose mode and enable consoler logger (using Amp\Log\ConsoleFormatter and Amp\Log\StreamHandler) I can see a bunch of output during the tests. But then AFTER I see PHPUnit output with X tests, Y assertions, Z errors, there comes additional output from that logger.

Something like "connection was closed because of X" - is that expected for the StreamHandler?

@prolic

This comment has been minimized.

Show comment
Hide comment
@prolic

prolic Sep 17, 2018

Contributor

throw new \Error("Loop stopped without resolving the promise"); - how can something like this happen? There is no Loop::stop() anywhere in the code. I can understand why throw new \Error("Loop exceptionally stopped without resolving the promise", 0, $throwable); can be thrown, but how can the loop be stopped without any exception?

Contributor

prolic commented Sep 17, 2018

throw new \Error("Loop stopped without resolving the promise"); - how can something like this happen? There is no Loop::stop() anywhere in the code. I can understand why throw new \Error("Loop exceptionally stopped without resolving the promise", 0, $throwable); can be thrown, but how can the loop be stopped without any exception?

@prolic

This comment has been minimized.

Show comment
Hide comment
@prolic

prolic Sep 17, 2018

Contributor

have you seen this? https://github.com/clue/reactphp-block/blob/master/src/functions.php#L54

this is used by reactphp for testing. very very similar to my wait-implementation, kind of different to yours.

Contributor

prolic commented Sep 17, 2018

have you seen this? https://github.com/clue/reactphp-block/blob/master/src/functions.php#L54

this is used by reactphp for testing. very very similar to my wait-implementation, kind of different to yours.

@kelunik

This comment has been minimized.

Show comment
Hide comment
@kelunik

kelunik Sep 17, 2018

Member

@prolic The event loop stops if there are no more watchers active or all left watchers are unreferenced. If you have to run the loop multiple times, that indicates a bug in your code.

Member

kelunik commented Sep 17, 2018

@prolic The event loop stops if there are no more watchers active or all left watchers are unreferenced. If you have to run the loop multiple times, that indicates a bug in your code.

@kelunik

This comment has been minimized.

Show comment
Hide comment
@kelunik

kelunik Sep 28, 2018

Member

Closing, as the issue has been fixed.

Member

kelunik commented Sep 28, 2018

Closing, as the issue has been fixed.

@kelunik kelunik closed this Sep 28, 2018

@kelunik kelunik added the question label Sep 28, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment