feat(services): php-fpm pools, one per installed PHP (T32) - #2
Merged
Conversation
…ree systems (T32)
`sys` is `linux/mod.rs` or `macos/mod.rs`, not `unix/` — each names what it takes from there, and the new constant was written without being listed, so `process::CAN_SIGNAL` resolved on Windows alone.
…(T32) Two refusals, both measured against 8.3.33 and both invisible on Windows, where there is no validator to run: - `include=<etc>/pool.d/*.conf` is a hard error when the directory is missing — not the warning an empty one gets — and that directory cannot exist for the first `--test`, which judges a staged file while `include` names the installed path. Phase 4 brings the line and the directory together; the file says so where the line was. - `--test` opens `error_log`, and the service log directory is otherwise created by the log sink, which is to say at the first start. Rendering creates it now, before the render is judged.
…nds (T32) The signal is delivered by the time `signal` returns; the wait after it is there so the next change does not land on a pool still cycling its workers. Logging on the far side of it stamped daemon.log ten seconds late.
…k (T32) `--version`'s sibling and there for the same reason. A declared set fails whole when one row cannot be rendered, so a fixture PHP that refused `--test --fpm-config` took every `service.*` call in the daemon suite down with it on both Unix systems. The file is read rather than assumed.
…(T32) The sudo fallback passes the environment explicitly, and the new variable was not on the list — so that leg would have warned that no PHP was found while one was sitting in the runner's temp directory.
…acing it (T32) The fixture handles no SIGHUP and Rust installs none, so the default disposition ends it — which the old test read as "it survived" only because the check beat the kernel to it. It now waits for the leader's lock to free (that is the delivery) and asserts the child's is still held (that is the target). Keeping the child alive also keeps the group alive, so the stop afterwards is an ordinary stop: macOS answers EPERM to a group whose every member is a zombie, which is how this surfaced and which the roadmap now records.
…s exist A Windows CI run of this branch served a log tail out of `current.log` because the daemon's ring was still empty, and the mechanism the code supports is a real gap rather than only a slow runner: `Runner::relay` subscribes to a capture whose reader threads are already broadcasting, so the lines printed in between reach the file and never the ring. Written up as T16c against T16b's path, since T32 caught it rather than caused it. The CI job table in build-and-release.md describes six jobs and three of them exist; say so where the table is, not only in ci.yml's opening comment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Roadmap task T32 — one php-fpm pool per installed PHP, a socket or port per pool, and reload by
SIGUSR2. This is the first service whose binary does not come from a package: it lives inside aruntime_installsdirectory, soservicesgrew a second typed parent (runtime_install_id, with aCHECKthat exactly one of the two is set) rather than a fakepackagesrow. It is also what theother half of T28 was waiting for, and the first refusal
runtime.uninstallhas ever been able tomake.
What the task settled
#[cfg].Recipe::specbranches oncfg!(windows)— a value,not an attribute — so both arms compile everywhere and a unit test exercises the arm the machine is
not. Which binary it is comes from the artifact's own
providesmap, so the index decides and norecipe writes a path down.
php-cgi.exewas measured rather than assumed: it isalready a process manager — php-fpm with
pm = static, configured through the environment insteadof a file — so this task writes no supervisor of its own.
max_children,max_requests,request_timeout,ready_timeout_ms,stop_grace_ms), rendered into a file or an environment as the platformrequires. Deliberately no
pm = dynamic, which Windows cannot express.ReloadBehaviour::Signal:mixengine-platformgainsCAN_SIGNALandSupervised::signal,addressed at the leader where a stop is addressed at the group, and answering
unsupportedonWindows exactly as
ask_to_stopdoes.service.createfor a pool. An idempotent hook runs after every install and atboot, so a PHP installed by an earlier build gets its pool with no data migration, and a home whose
row was deleted by hand repairs itself.
How it is judged
Against a real PHP on all three systems, through the FastCGI protocol — a pool that listens and
cannot execute anything accepts a connection exactly like one that works.
mixengine-testkitgaineda minimal responder client;
crates/mixengine-cli/tests/php_fpm.rsinstalls a real artifact throughruntime.install, starts the pool the hook created, reads a body back, changes an override, andasserts what each system actually does: Unix serves the new configuration from the same pid, Windows
says in
daemon.logthat it cannot and keeps the old one.Fixes CI asked for
CAN_SIGNALwas on neither Unix re-export listinclude=glob whose directory is missing, and--testopenserror_log--test --fpm-configMIXENGINE_PHP_RUNTIMEdid not cross into the isolated namespaceFour of those six exist only on Unix and cannot be seen from Windows, which runs no validator at all.
Written down rather than fixed
EPERMtokill(-pgid, ...)when every member of the group is already a zombie, andunix/process.rsforgives onlyESRCH. No test reaches it and the runner does not either.reach
current.logand never the ring — T16c, against T16b's path, caught by a run of thisbranch rather than caused by it.
CI is green on all three operating systems:
lint,test×3,bench×3.