-
Notifications
You must be signed in to change notification settings - Fork 7.9k
opcache: fix revalidation in long running CLI scripts #18671
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
base: PHP-8.3
Are you sure you want to change the base?
Conversation
8d75fcd
to
702c189
Compare
702c189
to
e210c08
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically the patch looks OK and the general idea makes sense.
However, the original behavior also makes sense for the most use cases and for the "static" CLI apps the new behaviour would introduce useless gettimeofday syscalls.
Instead of the new behavior for CLI mode only, I would think about consistent landing of this future in general. For example, we may define a new special opcache.revalidate_freq=-1
setting.
Hi @dstogov, Thank you for taking the time to review the patch and for the thoughtful feedback. I may have misread your suggestion to use To achieve that without overloading revalidate_freq, would you be open to adding a dedicated switch, e.g.
Default would remain 0 for all SAPIs, preserving today’s behaviour; setting it to 1 would enable the new moving-window logic while still honouring revalidate_freq. In this case I can remove SAPI check in the patch as this may be controllable through separate php-cli.ini. If this sounds acceptable I’ll update the patch, add the new ini entry to both development and production templates, and ping you for another look. Thanks again for your guidance! |
I wouldn't introduce a new INI directive.
This is my personal opinion. @iluuu1994 @nielsdos @arnaud-lb may be you have ideas how to land this in the best way? |
To be honest, I'm questioning whether this is necessary. Dynamically changing PHP files on-the-fly will only work when they don't contain any declarations (i.e. they are repeatedly imported with Can you clarify whether this is a real-life issue you're experiencing, or whether this is a theoretical issue? |
@iluuu1994, Thanks for reviewing and for questioning the real-world value. In our production setup we run a long-lived CLI daemon that forks workers to process background jobs. Opcache must stay enabled for start-up speed and memory sharing, yet the workers need to read small, declaration-free PHP files that carry feature-flags and other config data. Those files are included inside the hot loop so that every fork can observe updates without restarting. With current upstream behaviour the master and its children never see a modified config until the whole process restarts; with the proposed "dynamic reference time", the next include (after the usual revalidate_freq window) detects the new mtime and transparently refreshes the cached opcode. That gives us fresh configs while adding only one extra stat() per include every few seconds, which is negligible in this workload. We did trial other options: blacklisting config files removes optimizations at all and also requires re-reading even if the files did not change. A complete switch to, e.g., JSON config files adds parsing costs. However, some of these performance gains may be not so much in PHP 8.x and with the modern hardware. I'll try to -reevaluate these options. |
Another possibly unorthodox approach might be to install a timer in CLI that updates some global to be used for the comparison. Although I'm not sure what a sensible interval would be. Can I ask which part of your application changes the config? Might it be possible to invoke some endpoint to clear the config cache using |
No feedback was provided. The issue is being suspended because we assume that you are no longer experiencing the problem. If this is not the case and you are able to provide the information that was requested earlier, please do so. Thank you. |
@Sannis WDYT? |
Hi @iluuu1994, apologies for the delayed reply as I'm working on patches like this in my spare time, as part of our broader effort to contribute upstream improvements from our production stack at Bumble. Let me give a bit more context on the real-world use case behind this patch. We have a centralized configuration distribution system that synchronizes config files across multiple datacenters and thousands of servers running PHP. These include both PHP-FPM instances and PHP-based services using a long-lived CLI model, where workers are forked and reused for background jobs. This configuration system functions somewhat like a templating engine (e.g., Consul Template), generating small, declaration-free PHP files containing dynamic flags and settings. These are consumed by long-running CLI children, and it's important for each forked process to eventually observe updates to these files without requiring a full service restart. We did explore the idea of calling That said, I completely understand your hesitation and appreciate the discussion. If there's a better way to land something like this in core — even if it's behind a compile flag, or made available only in future versions — I'd be happy to adapt the patch accordingly. If you think that this is better to form as an RFC and there are a chance for positive voting — I'm also in. Otherwise, we’ll likely continue using a patched build internally and move on to the next patch in our upstreaming list — hopefully one with broader value to the PHP community 🙂 Thanks again for your thoughtful input! |
Thanks for the explanation. I suspect most people would use a key-value database for similar purposes, but I can see the appeal of dodging more infrastructure. I don't object to this change if it solves a real-world problem (with an opt-in approach, that is), but it would be good to have a short discussion on the mailing list. Maybe other people are facing similar challenges and have already implemented different strategies. There's a risk for cache stampede with your setup (small cache files filling shm over time, causing simultaneous restarts and recompilations), but I'm guessing this is a non-issue if you're already using this approach? |
@Sannis did you consider manually checking the timestamp of the generated files before including them, and calling |
This would also avoid the overhead for all but the include of the config file. |
It looks like opcache was initially designed with short-lived requests in mind, so when checking if the file should be re-validated, the code uses 'request time' instead of 'now', where request time is calculated once on the script startup. Which basically means that in CLI this check will never succeed.
This PR containing the patch to fix this issue covered with a test that passes in this branch but not in PHP-8.3.
The issue itself is older, but I rebased the patch to PHP-8.3 as mentioned in CONTRIBUTING doc.
Not sure if I must fill the issue separately, but will be happy to do if needed.