From 86d618b850c11688453b5a51ad7c66ca4d0e6148 Mon Sep 17 00:00:00 2001 From: Brandon Payton Date: Tue, 23 Jul 2024 19:35:10 -0400 Subject: [PATCH] Only rotate PHP runtime when there has been a runtime crash --- .../node/src/test/rotate-php-runtime.spec.ts | 27 ++++++++++++++++++- .../universal/src/lib/rotate-php-runtime.ts | 11 ++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/php-wasm/node/src/test/rotate-php-runtime.spec.ts b/packages/php-wasm/node/src/test/rotate-php-runtime.spec.ts index 92aab4e8f8..1688fec8e4 100644 --- a/packages/php-wasm/node/src/test/rotate-php-runtime.spec.ts +++ b/packages/php-wasm/node/src/test/rotate-php-runtime.spec.ts @@ -88,7 +88,7 @@ describe('rotatePHPRuntime()', () => { expect(recreateRuntimeSpy).toHaveBeenCalledTimes(2); }, 30_000); - it('Should recreate the PHP runtime after PHP crash', async () => { + it('Should recreate the PHP runtime after a PHP runtime crash', async () => { const recreateRuntimeSpy = vitest.fn(recreateRuntime); const php = new PHP(await recreateRuntimeSpy()); rotatePHPRuntime({ @@ -101,10 +101,34 @@ describe('rotatePHPRuntime()', () => { await php.dispatchEvent({ type: 'request.error', error: new Error('mock error'), + source: 'php-wasm', }); expect(recreateRuntimeSpy).toHaveBeenCalledTimes(2); }, 30_000); + it('Should not recreate the PHP runtime after a PHP fatal', async () => { + const recreateRuntimeSpy = vitest.fn(recreateRuntime); + const php = new PHP(await recreateRuntimeSpy()); + rotatePHPRuntime({ + php, + cwd: '/test-root', + recreateRuntime: recreateRuntimeSpy, + maxRequests: 1234, + }); + // Trigger error with no `source` + await php.dispatchEvent({ + type: 'request.error', + error: new Error('mock error'), + }); + // Trigger error with request `source` + await php.dispatchEvent({ + type: 'request.error', + error: new Error('mock error'), + source: 'request', + }); + expect(recreateRuntimeSpy).toHaveBeenCalledTimes(1); + }, 30_000); + it('Should not rotate after the cleanup handler is called, even if there is a PHP runtime error', async () => { const recreateRuntimeSpy = vitest.fn(recreateRuntime); const php = new PHP(await recreateRuntimeSpy()); @@ -124,6 +148,7 @@ describe('rotatePHPRuntime()', () => { php.dispatchEvent({ type: 'request.error', error: new Error('mock error'), + source: 'php-wasm', }); expect(recreateRuntimeSpy).toHaveBeenCalledTimes(2); diff --git a/packages/php-wasm/universal/src/lib/rotate-php-runtime.ts b/packages/php-wasm/universal/src/lib/rotate-php-runtime.ts index fae1ab2ad8..8f159cbc80 100644 --- a/packages/php-wasm/universal/src/lib/rotate-php-runtime.ts +++ b/packages/php-wasm/universal/src/lib/rotate-php-runtime.ts @@ -1,4 +1,5 @@ import { PHP } from './php'; +import { PHPEvent } from './universal-php'; export interface RotateOptions { php: PHP; @@ -57,11 +58,17 @@ export function rotatePHPRuntime({ await rotateRuntime(); } - php.addEventListener('request.error', rotateRuntime); + async function rotateRuntimeForPhpWasmError(event: PHPEvent) { + if (event.type === 'request.error' && event.source === 'php-wasm') { + await rotateRuntime(); + } + } + + php.addEventListener('request.error', rotateRuntimeForPhpWasmError); php.addEventListener('request.end', rotateRuntimeAfterMaxRequests); return function () { - php.removeEventListener('request.error', rotateRuntime); + php.removeEventListener('request.error', rotateRuntimeForPhpWasmError); php.removeEventListener('request.end', rotateRuntimeAfterMaxRequests); }; }