Repository navigation
add(core): FrankenPHP worker mode - #2535
Conversation
|
Review of head 1. Reset cached route controllers between kept-app requestsApplicationSnapshot captures directly referenced objects, but does not traverse objects inside arrays. Laravel's RouteCollection stores Route objects in arrays, and A controller retaining a constructor-injected Request or other request-specific state can therefore reuse that state on a later invocation, even after container instances are restored. Requested change: reset cached controllers and relevant route-level request state between requests. Add a regression test with two requests to the same controller, different users/request values, and verify the second invocation receives only its own state. Closure-only routes do not cover this case. 2. Keep Eloquent boot state consistent with restored event listenersSnapshot restoration restores the shared event dispatcher's listeners, while A model first booted after the snapshot can lose its registered event listeners while remaining marked as booted. Subsequent requests then skip booting it again. This concerns late-booted custom/package models; it is not a claim that every built-in model is affected. Requested change: restore model boot/global-scope state consistently with dispatcher state. Test a model first instantiated during request one and verify its 3. Execute the actual worker smoke tests before mergeThe reviewed checks showed 12 successes and one skipped Docker job. In build.yml, this job runs only on push/manual events and contains the actual FrankenPHP smoke tests. The PR's green checks therefore do not establish that these runtime tests passed. Requested change: provide a successful runtime run for the reviewed head covering If keeping the initial change smaller is preferable, the experimental KEEP_APP lifetime could be split from basic opt-in worker support. Review by SokilAI, AI assistant to Serhii Korneliuk. |
Prototype:
EVO_WORKER_KEEP_APP=1This PR introduces an experimental mode that preserves the initialized Evolution CMS application between requests in FrankenPHP Worker Mode, reducing repeated bootstrap overhead.
How it works
Service providers are bootstrapped once per worker, after which a snapshot of the application state is captured.
After each request:
flushState()orResetInterfaceare reset through their respective hooks.Core::initialize(), after the snapshot.Providers always boot before the session starts. With the default
EVO_SESSION=true, the session proxy loads the session inCore::initialize(). WithEVO_SESSION=false, a worker now starts the native session inCore::initialize()too, instead of incore/bootstrap.phpor at the top ofTracyServiceProvider.php. Duringboot(), providers therefore always see an empty session and a guest, in both worker lifetimes. Classic PHP isunchanged.
Performance benchmarks
The persistent application mode reduces request latency by approximately 44–61% compared to standard Worker Mode in these benchmarks.
Stability and compatibility
EVO_SESSIONsetting.Known limitation
Service providers that read the query string, cookies or request headers directly during
boot()see only those of the first request handled by the worker. They should read them per request instead: in middleware, in a pluginevent, or in a binding resolved during the request.
For this reason,
EVO_WORKER_KEEP_APP=1remains experimental. The limitation and usage details are documented inWORKER.md.