-
Notifications
You must be signed in to change notification settings - Fork 438
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Huge delay running task with nikic/PHP-Parser instance in parallel #815
Comments
Not sure what to do with this issue @InvisibleSmiley. Do know that the parallel implementation does not mean it is faster on 1 task. The parallel system triggers new php processes that run code inside GrumPHP. Booting these processes and initializing the code takes some time too. |
Slower than non-parallel mode (~2sec compared to ~1sec) but I guess that's OK.
As I said, it's hard for me to tell since I cannot debug the task in parallel mode, but since changing GrumPHP settings makes a difference I wanted you guys to check first before I open an issue with nikic/php-parser so the guys there don't just direct me here. I'd really appreciate it if you could somehow definitely rule out a GrumPHP issue here. |
Also note that if you replace $this->parser by $parser, i.e. only assign to a local variable rather than an instance variable, the delay does not occur. So the problem seems to occur somewhere after the creation of the object, which in my mind makes it more likely to be a problem with either GrumPHP itself or amphp/parallel. |
Ah yes, that might be the explanation! I'dd suggest moving the line from the constructor into a local variable inside the run method. That way, it doesnt get serialized in either the main or child process. |
Well if serialize() is indeed used then it must fail internally since the parser object contains a list of Closures which cannot be serialized. There is no error output though. I'd expect the call to fail and output an error message, ideally pointing in the right direction. Maybe it currently tries over and over again until it gives up? I guess the situation should also be documented somehow so other people know to keep the potential performance impact in mind. Note: The example I provided is reduced to show the issue. The real task contains another object as instance variable, and that object is created using a DI factory which creates and adds the parser object. So it's not at all obvious that the issue is the task serialisation. |
FYI: closures are serialized in amphp through https://github.com/opis/closure Having a DI factory inside your class isn't bad as long as you make sure that it can lazily load the parser inside the run method. Also the dependencies of the factory will be serialized, so be carefull what you put in there :) |
OK so I'll have to adapt our task implementation, understood. I consider Amp an implementation detail of GrumPHP, though. From a GrumPHP user's POV there's just tasks and the enabled-by-default option to let GrumPHP run tasks in parallel. So it really should be documented that GrumPHP, when in parallel mode, serializes tasks including all instance variables, recursively, which can lead to performance issues with large properties. A nikic/php-parser object instance may serve as an example. Agreed? 😃 |
Sure thing! We'll need to add it somewhere. |
Note: I'm not sure whether this is a bug with nikic/PHP-Parser or GrumPHP but it's hard to tell for me since I don't know how to debug parallel mode.
A task that keeps an instance of nikic/PHP-Parser (without actively using it!) takes much longer to complete in parallel mode.
Git commit
Steps to reproduce:
grumphp.yml:
composer.json:
src/ParserStub.php:
The text was updated successfully, but these errors were encountered: