Repository navigation
[Bug] process-queue-sequential: end a run that finds the command already running without exit() - #722
Conversation
…ady running without exit() SequentialProcessQueueCommand::execute() called exit(1) when another process held the command's lock. exit() inside Command::run() ends the PHP process before the Application dispatches console.terminate, so listeners never see the run end - e.g. a cron monitor's closing check-in is never sent and every overlapping cron run is reported as timed out - and the command cannot be run in-process. It now returns Command::SUCCESS after printing the same message: the run has nothing to do because another one is processing the queue, as in the example of Symfony's LockableTrait. process-queue-parallel has the same exit(1) through Pimcore's Parallelization trait, fixed in pimcore/pimcore. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are recorded for the focused lock-contention change intended to preserve Symfony’s command lifecycle.
No open issues 🎉
What changed in this PR
The PR addresses overlapping sequential queue runs exiting PHP before Symfony can dispatch console.terminate. It fixes the command-owned early-exit path rather than working around it in monitoring code (src/Command/SequentialProcessQueueCommand.php:60–65).
Changes:
- Replaces
exit(1)withreturn self::SUCCESSwhen the lock is unavailable. - Preserves the existing message and adds a comment explaining why normal command completion matters.
The observable compatibility change is intentional: lock contention now returns status 0 instead of terminating with status 1; the method signature is unchanged. The fix is local to the sequential command; parallel-command handling is outside this diff.
Runtime event dispatch was not independently verified. No automated regression test or documentation/changelog file is included; the PR description reports manual verification and explains the behavior change.
| File | Description |
|---|---|
src/Command/SequentialProcessQueueCommand.php |
Returns success on lock contention so Symfony can complete the command lifecycle. |
Review effort: Balanced



Changes in this pull request
Fixes pimcore/platform-version#714
When another process holds the command's lock,
SequentialProcessQueueCommand::execute()printsThe command is already running.and callsexit(1).exit()insideCommand::run()ends the process before the Application dispatchesconsole.terminate. As a result, listeners never see the run end: a cron monitor (Sentry Crons) that closes its check-in on terminate reports every overlapping cron run as a timeout during a long import. The command also can't be run in-process.It now prints the same message and returns
Command::SUCCESS. The run had nothing to do because another process is already working through the queue, and Symfony'sLockableTraitexample handles the same case the same way. Nothing else changes; the lock was never acquired on this path, so there is nothing to release.datahub:data-importer:process-queue-parallelreaches the sameexit(1)throughPimcore\Console\Traits\Parallelization, which is fixed in pimcore/pimcore#19622 (pimcore/platform-version#713). No change is needed in this repository for that one.How to reproduce
datahub:data-importer:process-queue-sequentialwhile another run holds its lock (or hold the lock yourself:Pimcore::getContainer()->get(LockFactory::class)->createLock('datahub:data-importer:process-queue-sequential', 60)->acquire(false)).console.terminatelistener, or in-process withsetAutoExit(false).Before: the process exits with status 1 inside
execute(), and the listener never runs. After:ERROR: The command is already running., exit code0, and the listener runs.Additional info
Checked on our install (data-importer 2.4.5 with this change applied as a patch; the code is identical to
2026.3). The command runs through a realApplicationwhile aFlockStorelock with its name is held. Before the change the process exits with status 1 andconsole.terminateis never dispatched. After it,execute()returns 0,console.terminateis dispatched with exit code 0, and the queue is not touched. I haven't added a Codeception test: the suite needs the full Pimcore stack, and the path is a singlereturn.🤖 Generated with Claude Code