Skip to content

use a separate resultCache per project config file - #1469

Closed
staabm wants to merge 6 commits into
phpstan:1.8.xfrom
staabm:separate-caches
Closed

staabm wants to merge 6 commits into
phpstan:1.8.xfrom
staabm:separate-caches

Conversation

@staabm

@staabm staabm commented Jun 23, 2022 •

Copy link
Copy Markdown
Contributor

closes phpstan/phpstan#7379
closes phpstan/phpstan#7601

With this patch we see analysis time dropped to ~5 seconds from previous 2-3 minutes in mono-repo projects, which contain several phpstan.neon files.

Comment thread src/Command/AnalyseApplication.php Outdated

@staabm staabm Jun 23, 2022 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while thinking about the idea suggested in phpstan/phpstan#7379 (comment) I came to this - in my eyes - even simpler solution to the problem.

instead of fiddling with all the different path-types involved we just use a separate resultCache-name per project-configuration file.

tbh the solutions seems to be to simple, so I think it might have some serious problems somewhere ;-).

in case we can proceed with this idea, I would check the current build errors and see how to actually test this change... at least the local testing on my project suggests that it is now using the result-cache where it didn't before.. so it seems to solve my problem at hand.

any feedback is welcome.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The $resultCacheName parameter of restore method shouldn't be misused for this, its usage is reserved only for PHPStan Pro purposes. It puts the result cache file in a subdirectory, I don't want to complicate it like that.

But hey - the logic you're doing here depends on $projectConfigArray and that is entirely available in restore() method too, so you can do the logic based on that there. A lot of useful values that can be used in the hash computation logic are already in the constructor/can be asked for there so I think this idea has wings.

@staabm staabm Jun 24, 2022 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adjusted per feedack and manually tested locally.

do we need a automatic test for the case? if so where and what to test (might be a bit hard because of random file-names involved)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw: in the docs there is no resultCachePath mentioned.. should it be added?

https://phpstan.org/config-reference#caching

@staabm
staabm marked this pull request as ready for review June 23, 2022 14:30
Comment thread src/Command/AnalyseApplication.php Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The $resultCacheName parameter of restore method shouldn't be misused for this, its usage is reserved only for PHPStan Pro purposes. It puts the result cache file in a subdirectory, I don't want to complicate it like that.

But hey - the logic you're doing here depends on $projectConfigArray and that is entirely available in restore() method too, so you can do the logic based on that there. A lot of useful values that can be used in the hash computation logic are already in the constructor/can be asked for there so I think this idea has wings.

@staabm
staabm force-pushed the separate-caches branch from c6d5ecf to d6af959 Compare June 23, 2022 19:05
@staabm
staabm marked this pull request as draft June 23, 2022 19:41
@staabm
staabm force-pushed the separate-caches branch from fff3d06 to b235560 Compare June 23, 2022 19:47
@staabm
staabm force-pushed the separate-caches branch from 1f38eba to 7ae6a7e Compare June 24, 2022 07:59
@staabm
staabm marked this pull request as ready for review June 24, 2022 08:01
@clxmstaab
clxmstaab force-pushed the separate-caches branch 4 times, most recently from 2c1a994 to 90d9217 Compare June 24, 2022 08:12
@staabm staabm mentioned this pull request Jun 24, 2022
@staabm
staabm force-pushed the separate-caches branch 3 times, most recently from c8658a0 to 67e8c4b Compare June 27, 2022 12:02
@staabm
staabm changed the base branch from 1.7.x to 1.8.x June 29, 2022 14:41
@staabm
staabm force-pushed the separate-caches branch from b6dda79 to 3d85276 Compare June 29, 2022 14:41
@staabm
staabm marked this pull request as draft June 29, 2022 14:57
@clxmstaab
clxmstaab force-pushed the separate-caches branch 2 times, most recently from ea060a9 to c711f0d Compare June 30, 2022 15:17
@staabm
staabm marked this pull request as ready for review June 30, 2022 15:19
@staabm

staabm commented Jun 30, 2022

Copy link
Copy Markdown
Contributor Author

added a test-case. should be good to go.

Comment thread tests/e2e/ResultCacheEndToEndTest.php Outdated

@staabm staabm Jun 30, 2022 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since checking exactly which hashes are generated is a bit too much IMO, I just verified phpstan will create result-cache files including some suffix (aka. the hash), which it did not do before this change.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the tmpDir case is already covered by an existing test which uses a tmpDir

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this condition is covered by #1475

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only thing I am not 100% sure: what needs to be here in this hash.

maybe just the $this->analysedPaths are already enough, since these are the absolute paths within the system..?

@staabm
staabm force-pushed the separate-caches branch 2 times, most recently from 286d1f6 to 3ac86ba Compare July 10, 2022 12:34
@staabm

staabm commented Jul 10, 2022

Copy link
Copy Markdown
Contributor Author

@ondrejmirtes anything I can do to get this merged?

@staabm
staabm force-pushed the separate-caches branch from 3ac86ba to 7ff840b Compare July 18, 2022 18:31
@staabm
staabm marked this pull request as draft August 30, 2022 07:04
@staabm
staabm marked this pull request as ready for review August 31, 2022 11:18
@herndlm

herndlm commented Aug 31, 2022

Copy link
Copy Markdown
Contributor

I'm looking forward to this feature too. I should be able to get rid of some local config entries most likely :)

@herndlm

herndlm commented Dec 19, 2022

Copy link
Copy Markdown
Contributor

sorry, for the "bump", but I just thought about this PR and was wondering about its state and/or if it was forgotten maybe :)

@ondrejmirtes

Copy link
Copy Markdown
Member

I'm a bit afraid to touch this area because it's hard to test it.

@SanderMuller

Copy link
Copy Markdown
Contributor

Still live on current 2.2.x, and a bit broader than the issues describe. Two configs in one project, run alternately: every run after the first reports metadata do not match: projectConfig, analysedPaths, so neither config ever gets a warm cache. And since the default tmpDir is sys_get_temp_dir() . '/phpstan', two unrelated projects on one machine do the same to each other whenever neither sets tmpDir - I reproduced that with two throwaway projects, 6 runs, 5 full re-analyses.

On the "hard to test" worry: it is much easier to pin now than in 2022. The result-cache e2e blocks are plain shell, so alternating two configs and asserting Result cache restored. 0 files will be reanalysed. is a few lines, and a block can clear the machine temp dir first for the default-tmpDir case. Happy to contribute that fixture, as a failing test first if you prefer that shape.

Two things I noticed in the patch while reproducing:

  • the per-config path only applies when neither tmpDir nor resultCachePath is set, so a project that keeps its cache in the repo for CI (tmpDir: .cache/phpstan, several configs) keeps thrashing;
  • the name is an md5 of analysedPaths plus bootstrapFiles, so two configs over the same paths that differ only in level still land on one file and still invalidate each other - that was my first reproduction.

Deriving the name from the same projectConfig array the metadata already builds would cover both.

@ondrejmirtes

Copy link
Copy Markdown
Member

Hey, this is very close to my current interest and headspace so I can think about it clearly. Can you please open a new issue and describe what we learnt meanwhile, what use cases should this solve and how does the recent relativization of paths in the result cache relate to this? (It might solve some of the use cases.)

Also I think the git worktrees might be relevant here.

What I have to say about this now is that thanks to relative paths, even if we don't set a local tmpDir and just use the system one, if we copy a project to a different directory on disk, PHPStan should be able to reuse the same result cache without invalidation (when the projects are very similar).

But of course if something in the meta changes we need to have a separate result cache so that's where the discussion should start.

Feel free to mention these points in the description too, we will build on them too.

@SanderMuller

Copy link
Copy Markdown
Contributor

Opened as phpstan/phpstan#15163, with your points in the description.

Your hunch about relative paths checks out in the strongest form: a project copied to a different directory, PHPStan in its own vendor, no local tmpDir, reuses the cache with 0 files will be reanalysed. It stops applying when PHPStan lives outside the project, since the anchor is %rootDir% and then it does not move with the copy.

The worktree measurements are in there too, along with the two remaining thrash cases and a suggestion for where the file name could come from.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Name resultCache.php file more uniquely in global tmpDir Spontaneously started crashing for no obvious reason

5 participants