Follow-ups for the background worker stack

Open
#2,657 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Refactor
Clarity
Needs clarification
Activity status
Active
Tech stack
go, php
Domain
backend

Research direction

Start with #2617 and #2636, then read the linked discussions and the worker entry points named here: Start(), Init(), Validate(), workerLifecycle, and the worker/task handle paths. Choose one unchecked follow-up; it is done when that specific configuration, lifecycle, thread-budget, handle, or platform-channel behavior is implemented and the corresponding checklist item can be verified.

Written by the indexing model from the issue text.

Description

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: frankenphp.Validate() reports what Init() would refuse without starting anything, and the Caddy app implements caddy.Validator on it, so a rejected reload leaves the running site serving. Done in #2661.

  • Synchronize the startup-failure boundary: publishing ShuttingDown wakes 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_r3987787784

  • Pull the rest of the common bookkeeping into workerLifecycle once that boundary has one shape. https://github.com/php/frankenphp/pull/2617#discussion_r3987787771

  • Stop making people compute the thread budget by hand: num_threads now counts the threads for the requests no worker serves, workers coming on top, in #2660. No new option in the end, max_threads keeps bounding the whole process.

  • Implement Io\Poll\Handle on FrankenPHP\WorkerHandle and the task handles, done in #2617 and #2636 on top of the 8.6 job of #2658

  • Make the per-task php_stream of #2636 optional: the state of each side moved onto its handle, the task settles in the handle's cleanup, and getStream() builds the stream on demand, so a script waiting through a context allocates neither a stream nor a resource per task. Done in #2636.

  • Recycle the task handles: measured and dropped. A per-thread pool of the per-side state benches flat against #2636 (39.1 -> 38.7us a task, throughput within 1.4% either way, 15.4 syscalls on both sides, fork run 35466429028), since the engine already recycles the object slot and what is left is one 72-byte block per side.

  • Give macOS the channel Linux gets from eventfd: done in #2636 with a kqueue descriptor carrying an EVFILT_USER event, one per side. Measured on a macos-latest runner before writing it, per wake-up round trip: socketpair 16.1us, two pipes 14.0us, kqueue 11.7us, the same quarter eventfd takes off the pair on Linux (23.1 -> 17.5us on the same runner class). Windows keeps the socket pair for php_select().

Dominant language
Go
Stars
11.3k
Forks
488
Avg merge
2d 4h
Merged PRs (30d)
13

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from php/frankenphp

All issues in php/frankenphp

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.