-
Notifications
You must be signed in to change notification settings - Fork 273
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Memory leak: add rotatedPHP to kill and recreate PHP instances after …
…a certain number of requests (#990) Swaps the internal PHP runtime for a fresh one after a certain number of requests are handled. ## Rationale PHP and PHP extension have a memory leak. Each request leaves the memory a bit more fragmented and with a bit less available space than before. Eventually, new allocations start failing. Rotating the PHP instance may seem like a workaround, but it's actually what PHP-FPM does natively: Implementing this solution in core enables all downstream consumers of the PHP WASM package, like `wp-now`, to benefit. ## How it works Adds a `rotatePHP` function that keeps track of the `BasePHP.run()` calls and replaces the Emscripten runtime with a new one after a certain number of calls. Example: ```ts const loadRuntime = async () => { return await NodePHP.loadRuntime("8.0"); } const php = await rotatedPHP({ php: new NodePHP(await loadRuntime(), { documentRoot: '/test-root', }), recreateRuntime: loadRuntime, maxRequests: 50 }); // After 50 request() calls, the PHP runtime will be discarded and a new one will be created. // It all happens internally. The caller doesn't know anything about this. ``` I started by porting the "Process Pool" idea ([see the branch](https://github.com/WordPress/wordpress-playground/compare/harvested-memory-pool?expand=1)) from WordPress/playground-tools#110, but I realized that: * The logic was complicated * We only need to manage a single PHP instance, not a pool of them * Worker thread is built to a single PHP instance and not architected to handle a pool So I decided to simplify the logic and just manage a single PHP instance. ## Other changes * Implements `BasePHP.hotSwapPHPRuntime()` that opens the door to switching PHP versions dynamically and without a full page reload. * Makes the `BasePHP.semaphore` property public to enable conflict-free runtime swaps * Adds the `runtime.initialized` and `runtime.beforedestroy` events for OPFS handlers to re-bind on runtime swap. * Tiny unrelated change: Migrates the OPFS handler from monkey-patching the `php.run` method to relying on event listeners. The `rotatePHP` function went through a similar journey and I updated that other code path while I was on it. Supersedes WordPress/playground-tools#110
- Loading branch information
Showing
13 changed files
with
547 additions
and
167 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Oops, something went wrong.