Fix captureOutput stale cache, ExecuteTask path tokenization; add ops doc#496
Merged
Conversation
… doc
Two correctness bugs from the source-grounded review plus the ops-first
documentation strategic item.
1. Processor::captureOutput() cached the auto-detected schema result for
the lifetime of the worker. A long-running worker started before
`bin/cake migrations migrate` added the `output` column to the
queued_jobs table would then see the cached `false` for the rest of
its runtime and silently drop captured stdout until restart. The
auto-detect path now re-checks the schema per call; explicit config
(Configure::write('Queue.captureOutput', ...)) is still memoised
because that branch never changes mid-process. The per-call cost is
a single schema lookup against an already-cached description.
2. ExecuteTask::add() tokenised the human-friendly CLI input with
`explode(' ', $data, 2)`, which split a quoted command path with
embedded spaces in half — e.g. `"/usr/local/bin/My Tool" arg1` ended
up with the path mangled across `command` and `params[0]`. Switched
to `str_getcsv` with space as the delimiter and double-quote as the
enclosure, so quoted command paths survive intact. The plain
`cmd arg1 arg2` shape continues to work the same way it did before.
Two regression tests:
- testAddPreservesQuotedCommandPathWithSpaces — quoted path round-trip
- testAddTokenizesPlainSpaceSeparatedArgs — bw compat for the simple case
3. docs/guide/operations.md is a new ops-first page covering: sizing
workers, supervisor / systemd unit shapes, monitoring signals worth
alerting on (stale workers, backlog growth, per-task failure rate),
failure-handling workflow (admin dashboard, queue retry, the
workaround dead-letter pattern until a formal DLQ ships), schema
migrations on live workers (the captureOutput re-check above lets
you add columns without restarting workers), multi-server pitfalls,
and common task-author traps. Linked from /guide/ and the sidebar.
phpunit (186/186 + 7 skipped), phpstan, phpcs all clean.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #496 +/- ##
============================================
+ Coverage 77.55% 78.01% +0.45%
+ Complexity 972 971 -1
============================================
Files 45 45
Lines 3262 3262
============================================
+ Hits 2530 2545 +15
+ Misses 732 717 -15 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
Summary
Two correctness bugs from a recent audit plus the ops-first documentation strategic item.
Processor::captureOutput()cached the schema check for the lifetime of the worker. A long-running worker started beforebin/cake migrations migrateadded theoutputcolumn toqueued_jobswould see the cachedfalsefor the rest of its runtime and silently drop captured stdout until restart. The auto-detect path now re-checks the schema per call; explicit config (Configure::write('Queue.captureOutput', ...)) is still memoised because that branch never changes mid-process. The per-call cost is a single lookup against an already-cached schema description.ExecuteTask::add()mangled quoted command paths with embedded spaces.explode(' ', $data, 2)split"/usr/local/bin/My Tool" arg1acrosscommandandparams[0]— the path arrived atrun()broken in half. Switched tostr_getcsvwith space delimiter + double-quote enclosure so quoted paths survive intact. The plaincmd arg1 arg2shape continues to work unchanged.The audit's other "bug 3" concern (the
escape => falsedebug-mode bypass) is already gated correctly by PR #485 — in non-debug mode the check at line 89 throws if escaping is disabled, and the allow-list check at line 94 rejects any non-listed command. Per the project's security-scoping convention, debug-gated paths aren't framed as bugs.Strategic: ops-first documentation
New
docs/guide/operations.mdcovers what the original audit flagged as missing operational guidance:Restart=always+ boundedworkerLifetimerecipe.bin/cake queue retry <job-id>, the workaround dead-letter pattern until a formal DLQ ships.captureOutputre-check above lets you add columns without restarting workers; anything more invasive needs a rolling restart.queue_processesheartbeat coordination story and theFileLockcaveat forcakephp-queue-scheduler.Linked from
/guide/index and the sidebar.Tests
phpunit (186/186 + 7 pre-existing skipped), phpstan, and phpcs all clean.
Three new tests:
ProcessorTest::testCaptureOutputReChecksSchemaWhenNotExplicitlyConfigured— memoised explicit-config branch + per-call auto-detect branch.ExecuteTaskTest::testAddPreservesQuotedCommandPathWithSpaces— quoted path round-trip.ExecuteTaskTest::testAddTokenizesPlainSpaceSeparatedArgs— backward compat for the simple case.