Repository navigation
Reuse loaded schema cache in long-running processes - #2804
Open
adilKhan72 wants to merge 2 commits into
Open
adilKhan72 wants to merge 2 commits into
adilKhan72 wants to merge 2 commits into
Conversation
Under Laravel Octane, a fresh ASTBuilder is resolved for every request, so ASTCache required the schema cache file each time. Without OPcache in the worker, this compiled the file and allocated the whole array again on every request, while the previous copy stayed alive until the next cycle collection. Keep the loaded cache file contents in memory for the lifetime of the process and reload them only when the file changes. Resolves nuwave#2436
| return $loaded['astArray']; | ||
| } | ||
|
|
||
| $astArray = Utils::requireArrayOrForget($this->filesystem, $path); |
Within opcache.revalidate_freq, requiring a replaced cache file can return the previously compiled array. Keeping that in memory under the new file fingerprint would serve the old schema until the worker restarts. Ask OPcache to recompile the file when it is newer than the cached script, and always when this process already loaded an older version.
Author
|
Good catch from the review, that was a real gap. If the cache file gets replaced within Fixed in bc1ac63: before loading the file again we call |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Resolves #2436
Changes
In long-running processes such as Laravel Octane, a fresh
ASTBuilderis resolved for every request, soASTCache::fromCacheOrBuild()required the schema cache file on every request. Without OPcache in the worker (opcache.enable_cli=0is the default for Swoole/RoadRunner), PHP compiled the file and allocated the whole AST array again each time. Because that array was only reachable through the request's app copy, Octane's GC listener could not free it until the following request, so two copies were alive at once.ASTCachenow keeps the loaded cache file contents in memory for the lifetime of the process and reuses them while the file is unchanged (inode, mtime and size, afterclearstatcache()).set(),clear()and missing or invalid files reset it, andASTCache::forgetLoaded()resets everything. The raw array is kept rather than theDocumentAST, so each request still gets its ownDocumentASTinstance.Measured with an 18 MB schema cache through Octane's
FakeWorker, 200 requests, OPcache off:With OPcache enabled, nothing changes (118 MB, 6–10 ms), since the stored array is the immutable one from shared memory.
I couldn't reproduce an unbounded per-request growth; the numbers above level off after ~20 requests, but the double copy plus compile overhead is enough to hit a 512 MB limit with a large schema, which matches the fatal error in the issue (raised while requiring
lighthouse-schema.php).Breaking changes
None.
Changelog
Fixed