octane
octane copied to clipboard
Automatically disable worker mode in local environments if workers aren't specified explicitly
This PR updates the FrankenPHP configuration to disable worker mode if the application is running in the local environment and the worker count is not specified explicitly (or set to auto).
The problem
FrankenPHP's Worker mode keeps the application in memory, which does wonders for performance when running in production. Locally, however, it causes problems with XDebug, and does not reflect file changes immediately. The solution to the latter is configuring Octane to restart the worker after every request, thereby defeating most of the advantages of an application server in the first place.
The solution
By only enabling worker mode if the application is running in a non-local environment, it will be served in a CGI-like manner, i.e. what the built-in PHP server (used in artisan serve) does—and exactly what you'd expect to happen: XDebug just works, and changes to files are reflected immediately.
In production, worker mode will be enabled and all the benefits that come with it apply. We use the setup as provided in this PR in our production application and don't face any issues with it.
This solves https://github.com/dunglas/frankenphp/issues/931, and probably solves #928 too.
Could we detect if XDebug is installed and only disable the worker mode if it is?
It isn't by default and the worker mode improves performance even in dev mode.
Could we detect if XDebug is installed and only disable the worker mode if it is?
We could do ini_get('xdebug.mode') !== 'off', or possibly check APP_DEBUG in addition to the existing conditions?
It isn't by default and the worker mode improves performance even in dev mode.
Still, that would require either using watch mode (which in turn demands node and chokidar, which makes setup more complex in e.g. Docker) or limiting the server to MAX_REQUESTS=1, which isn't too good for performance either.
But @dunglas I respect if you want to approach this differently, and will close the PR—this is your domain.
@Radiergummi a problem with this approach is that Xdebug can be disabled (or enabled) for the CLI SAPI (which, generally, isn't using FrankenPHP), but enabled (or disabled) for the FrankenPHP SAPI. It's rare when using Docker, but more common when not using it.
Maybe would we store a tiny script detecting if Xdebug is enabled and run frankenphp php-cli the-detection-script.php to be more reliable?
We'll need to fix the tests before continuing.
@dunglas sorry for only getting back to this now, things were a bit tense on my end lately.
I just added a script as per your recommendation: Now, worker mode will be disabled if
- the amount of workers isn't set explicitly,
- we're running locally, and
- XDebug is not installed, or its mode is set to "off".
That should work as discussed earlier, no?
@Radiergummi What's the point of disabling worker mode locally when xdebug is off? For some applications, the difference is 50ms vs 300ms request times. Sure, we could just specify the workers explicitly (which we do), but I'm guessing most people don't do that. Plus, if we ever get automatic worker scaling in Franken, there would be no point in specifying the worker count explicitly through Octane, so even less people would actually be using --workers.
I suggest just sticking with ini_get('xdebug.mode') === 'off'. Either way it's a temporary solution till IDEs add support for XDebug's new control socket.
I would argue that disabling worker mode should be a conscious manual action (if the app is meant to be run in worker mode), even in DEV environment. IMO it's not about performance primarily, but consistent behavior. If app will run in worker mode, then it should be developed in worker mode as well, considering all the pitfalls of possible memory leaks and other worker intricacies.
php artisan serve is the alternative to running workers and Octane. Perhaps they can stick to that instead.
Or, as someone suggested above, only disable workers by checking the presence of Xdebug in dev environments.