Follow-ups for the background worker stack
Things left to do or decide after #2617 and its stack, so they don't get lost.
Validate a configuration before stopping the running one:
Start()callsInit()after the old app stopped, so any declaration error leaves the site down while Caddy rolls the configuration back. A side-effect-free preflight shared withInit(), called fromValidate(). https://github.com/php/frankenphp/pull/2617#discussion_r3987787721Synchronize the startup-failure boundary: publishing
ShuttingDownwakes the startup waiter before the thread finished its exit path, and a shutdown request is not distinguished from a thread that exited. Both worker handlers share that path. https://github.com/php/frankenphp/pull/2617#discussion_r3987787784Pull the rest of the common bookkeeping into
workerLifecycleonce that boundary has one shape. https://github.com/php/frankenphp/pull/2617#discussion_r3987787771num_regular_threads/max_regular_threads, so nobody computes the thread budget by hand. https://github.com/php/frankenphp/pull/2617#discussion_r3866053582Implement
Io\Poll\HandleonFrankenPHP\WorkerPollHandleonce PHP 8.6 can be tested in CI, so the handle registers on anIo\Poll\Contextdirectly instead of going throughStreamPollHandle. The interface is an empty marker, the contract is thephp_poll_handle_opshooks. https://github.com/php/frankenphp/pull/2617#issuecomment-5731032156Drop the per-task
php_streamfrom the common path of #2636, now that a handle's lifetime is exactly the task's: hold the task state in the object, settle infree_obj, and build the stream lazily ingetStream(), so a script that never multiplexes allocates no stream and no resource per task. Then recycle the handles themselves, through a per-thread free list. Channels stay eventfds on Linux; on macOS look for the equivalent, a kqueue descriptor triggered withEVFILT_USERis pollable and needs no pair, a pipe is the usual fallback (libuv's async handles), and Windows keeps the socket pair forphp_select().
Source: php/frankenphp