Open Radiergummi opened 1 month ago
On browsing the XDebug issue tracker, there's a related issue:
0002161: Breakpoints not updated when process is running
When a PHP is process is already running and you add a new breakpoint, it will never be triggered unless a script is restarted. https://bugs.xdebug.org/view.php?id=2161
Following that, Derick is just now implementing support for control sockets, allowing IDEs to inject new breakpoints into running PHP processes—such as the FrankenPHP worker.
IIUC, that means step debugging with XDebug was never actually possible without restarting FrankenPHP after configuring breakpoints?
Adding this information to the website would have saved us, and probably others too, a lot of time. At least to me it means that I'll revert from FrankenPHP back to the built-in webserver for now; not being able to use breakpoints in local development without restarting the server is a non-starter.
Edit: This is in no way meant to dismiss the amazing work of all FrankenPHP contributors. I'd just like to suggest clarifying the documentation on XDebug to make it clear step debugging doesn't really work for now, as the whole debugging story feels a little under-documented right now.
There are a workaround for that: not using the worker-mode or setting the max number of requests to handle with the worker mode to 1 (which is very similar to disabling the worker mode entirely). It's what we do in Symfony Docker for instance (the worker mode is disabled in dev, and enabled in production).
By setting max requests to 1, the synchronisation between the IDE and FrankenPHP is off-by-one—after setting a breakpoint, you need to request the old code once, the worker restarts and the breakpoint becomes active; after disabling the breakpoint, you again need to do an additional request, which triggers the (now-gone) breakpoint again, and only after that things are back to normal.
However, disabling the worker mode is the way to go. This isn't as straightforward in Laravel Octane, which doesn't seem to anticipate someone might want to do this. By using a custom Dockerfile adapted from the one included with Octane, it's doable though.
If someone happens to stumble upon this, here's our solution:
(worker) {
worker "{$APP_PUBLIC_PATH}/frankenphp-worker.php" {$CADDY_SERVER_WORKER_COUNT}
}
{
{$CADDY_GLOBAL_OPTIONS}
admin {$CADDY_SERVER_ADMIN_HOST}:{$CADDY_SERVER_ADMIN_PORT}
frankenphp {
{$CADDY_SERVER_FRANKENPHP_OPTIONS:import worker}
}
{$CADDY_GLOBAL_EXTRA_DIRECTIVES}
}
# (Rest of the default config below)
All it requires you to do locally is set the CADDY_SERVER_FRANKENPHP_OPTIONS
environment variable to an empty string locally, using your Dockerfile or compose stack or whatever.
Thank you for pointing me in the right direction, the Symfony repository was very helpful. This is probably a Laravel issue after all, but I'm weary of Taylor silently dismissing PRs. This issue can be closed then, I guess. Again, thank you!
As the co-author of the FrankenPHP support for Octane, I'm probably the one to blame! IMHO a docs PR on Octane should to the trick. Or maybe an additional (temporarily) debug
flag?
The issue is, in my opinion, that the default Caddyfile included in Octane always uses the worker mode. I don't know how others solve this, but I try to keep our development environment as close to production as possible, and thus also want to use Octane locally.
I think the most Laravel-y thing would be to enable worker mode only if APP_ENV
is not local
, or probably check APP_DEBUG
is true?
Actually the issue occurs only when using Xdebug, maybe could we detect if XDebug is enabled or something like that.
@dunglas just so I can understand this correctly; from the default Octane config, FrankenPHP will start in worker mode, correct? So for changes made to the code to become live in development, users must set the maximum number of requests handled by workers to 1.
If that is true, what benefit does the worker mode offer for development, if Symfony Docker doesn't use it here either?
Worker mode is an optimization, for now anyway. As more and more devs get used to working with it (like these changes to xdebug) this will become less truer over time. Generally, you disable optimizations (like a compiled container, etc) during development to make it easier/faster to get feedback loops and iterate.
For now, there are things you have to manually do (kinda like not that long ago, we had to manually disable compiled DI containers in dev, now it's automated, most of the time). Things get better, all the time.
Right; that matches my understanding. So, maybe to rephrase my intent—couldn't we, then, update the Octane integration such that it would only enable worker mode if the application is running in production?
This would improve the development workflow for Laravel users, and work out of the box, without any userland modifications necessary.
I assume they accept PRs, so I assume it would be possible.
Describe you feature request
We'd like to use FrankenPHP for our Laravel application (running in Docker), but using it with XDebug isn't as straight-forward as the website claims it is:
MAX_REQUESTS=1
in the environment, a breakpoint triggered and then removed will be triggered again on a subsequent request, and only on the third request will it no longer be triggered.In combination, that makes debugging hard to use, which has encouraged some of our developers to go back to
dd()
—ugh!Hence, I would kindly like to ask for two thinks:
We're using PHP 8.3, Xdebug 3.3.2, Laravel 11 with current Octane, and the latest FrankenPHP Docker image (as a base image for our own).