SanderRonde / phpstan-vscode

PHPStan plugin for VSCode
https://marketplace.visualstudio.com/items?itemName=SanderRonde.phpstan-vscode
MIT License
37 stars 7 forks source link

Multiple PHPStan runs happening in parallel #80

Open berniedurfee-renaissance opened 1 month ago

berniedurfee-renaissance commented 1 month ago

I have a similar issue to this (https://github.com/swordev/phpstan-vscode/issues/11) when using this plugin.

I see many runs of PHPStan happening at the same time. Not sure if it's the same issue, but I don't see this issue on the command line.

I have max core usage for PHPStan set to 2 in my config:

parallel:
    maximumNumberOfProcesses: 2

Using PHPStan v1.11.1

vendor/bin/phpstan --version
PHPStan - PHP Static Analysis Tool 1.11.1
image
SanderRonde commented 1 month ago

In theory it should kill any running processes whenever a new one is spawned. I think it should be pretty easy to figure out where it goes wrong. If you open up vscode it should do a single check. If at that point you have many running processes then it's an issue with the config not being respected. If not then something might be going wrong with the killing of processes. Can you test that for me?

Something else it could also be: are you sure your config file is being used in the checks? You can verify by checking the logs of the extension in the output panel.

You can also run phpstan with the same command you see there to test out where it's going wrong.

berniedurfee-renaissance commented 1 month ago

If I'm very careful not to save often, the extension behaves fine. It's if I'm working fast, making changes and hitting CMD+S often that the processes start to pile up and it bogs my machine down to a crawl with so many PHPStans running simultaneously.

I think the PHPStan worker processes take some time to die.

I see the 2s wait time for the main process to die, but that might not be enough in some instances.

Maybe keep a loop going to be sure the processes are dead? Also, maybe check the child (worker) processes of the main PHPStan process to be sure they're all dead before proceeding to fire up a new process?

SanderRonde commented 4 weeks ago

There is indeed a 2 second timer for the process to exit gracefully. But after that a SIGTERM is sent, after which a SIGKILL is sent if it's still not behaving. Only when either the process exits or it takes 10s to exit does the extension move on and spawn a new one. I could consider bumping the 10s, but I'm not too sure if the extension will be able to be of any use if PHPStan resists being killed.

I could maybe look at the children of the main process but implementing a process-tree crawler that works cross-platform is really hard in node. Every platform has different semantics around these things.

A simpler alternative might be to get PHPStan Pro which has a watch mode that's built into the process itself. Meaning it itself watches instead of an external program (my extension in this case) spawning processes and killing them. By doing so you'll also support the creator (not me btw, I don't get anything from this endorsement). This extension integrates with the Pro mode by showing the errors that Pro collects in your editor and by starting/stopping pro mode as you open your project.

Ideally I'd of course want to fix the issue but it seems to be worse on a mac (at least I haven't heard anyone report it on a windows/linux device yet) and I don't own a mac so I can't reproduce it.

quazardous commented 3 weeks ago

Hi,

I don't know if it's related but sometime phpstan starts piling up project scan.

The bar show "phpstan scanning file 123/1567" (or something like that).

But I do not want phpstan to start project scan (or maybe once at startup). My projects has 1500+ files and my phpstan runs in docker. Just scanning current file is fine but maybe it's a chain effect with the dependencies ?

When it happens vscode just end up crashing on memory usage...

PS: I was not able to make phpstan server work using phpstan@docker. is there some documentation about it ?

EDIT: I'm under fedora 40

SanderRonde commented 3 weeks ago

That does sound like another issue. It's not so much piling up as it's just a single big scan happening. Sounds like the phpstan.singleFileMode setting is what you're looking for. By default this extension checks the whole project (since that's what the author of PHPStan recommends). But with that mode enabled it'll only perform checks for the current file.

The reason he recommends that is that in the long run, performing single-file checks is much slower. Since it invalidates the cache every time. That means it doesn't scan just the files that changed and its usages, but also needs to scan its dependents. So in the long run single-file-mode costs you more CPU time. If you've completed a succesful checks once, the cache will ensure checks from then on are much less heavy. But I can understand not going for complete checks on a relatively low-power machine.

I haven't used PHPStan inside docker myself so no documentation for it (yet). But you should be able to make it work by using the phpstan.binCommand setting, maybe using the phpstan.paths setting too (explanation here). There are also quite some issues on this repo discussing docker support so you might be able to puzzle it together based on those (such as #1).

wallacio commented 4 days ago

I think that does sound like another issue - albeit one that we're also seeing. Project contains > 2000 files/scripts, which renders VSCode unusable for 10-15 seconds after every save as PHPStan rips through the entire project. On a machine with 10th gen i7 CPU, that does seem abnormally long.

Enabling singleFileMode does improve things marginally but there's still a considerable delay between ctrl+s and being able to navigate method definitions etc by ctrl+click on method names, for example whilst "PHPStan checking..." whirls away in the status bar. I do only see a single php process running, so it's not like it's kicked off multiple processes.

Performance is preventing us from using this on-save so we'd love to find a solution. Any help in diagnosing this, if it's not related to other the other people in this issue's experiences would be appreciated. Fully appreciate it may be nothing to do with this extension, either.

SanderRonde commented 4 days ago

That does indeed sound unrelated to the extension. The performance hit probably comes from running PHPStan itself, which is spawned by the extension but since it's spawned in it shouldn't be hanging up the UI thread. If that's happening it's likely that your computer is just being maxed out. That's not surprising btw, when I run it on my own desktop PC (with a similarly powerful CPU) it also freezes completely. At my job we've got a massive 128-core beast of a dev-server that I can execute PHPStan on. Even on that thing it takes ~20s to check ~2k files and it consumes a large amount of processing power. PHPStan is pretty demanding.

You can test this out by just running PHPStan by itself on the commandline. If it's fast, it's the extension's fault. If it's slow, then it's PHPStan itself being slow :)

martijn-dd commented 4 days ago

I have the same as berniedurfee-renaissance on my Mac. PHP processes piling up.

I checked the extension log files of VS Code. In the PHPStan Client Log I noticed the following (hide the file path with ------) :

[check:23] Check started for file: ------ [check:22] Check completed for file, errors= {"fileSpecificErrors":{},"notFileSpecificErrors":[]} [check:23] Spawning PHPStan with the following configuration: {"binStr":"/opt/homebrew/bin/phpstan","args":["analyse","-c","------/phpstan.neon","--error-format=json","--no-interaction","--memory-limit=1G","--no-progress","------.php"],"tmpDir":"/tmp/phpstan"} [process-spawner] Spawning process 18610 with timeout 900000 [file-watcher] Checking: Document changed

with timeout 900000 => 900 seconds I guess? But in the extension settings the Project timeout is 300000 and the other timeout is 30000.

Maybe that timeout of 15 minutes could cause that it looks like the processes are not stopped/killed but takes longer than expected.

Let me know if I need to provide more details to help you solve the issue.

SanderRonde commented 4 days ago

Correct that's 15 minutes. There's two timeouts:

(I agree that logging-wise this is very unclear, might change that in the future)