Repository navigation
feat(magento): durable:worker drains the database queues (#736) - #1005
Merged
Merged
Conversation
…ut acknowledging it (#736)
… gives it back when the execution is held (#736)
…deadlock, a lost connection or an early resume (#736)
…als the run as failed (#736)
…e/durable is declared and refuses the Nexus role (#736)
…er command, not the minimal drain loop (#736)
…nal stops the worker between two messages (#736)
This was referenced Oct 7, 2026
# Conflicts: # UPGRADE.md # phpstan.neon # psalm.xml
gplanchat
changed the base branch from
feat/magento-runtime-factory-sql
to
main
October 9, 2026 12:01
gplanchat
marked this pull request as ready for review
October 9, 2026 12:01
gplanchat
added a commit
that referenced
this pull request
Oct 9, 2026
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.
Refs #736. Epic #740, backend key
database.Stacked draft: this PR is based on #1003 (
feat/magento-runtime-factory-sql), which sits on #1002 (feat/magento-sql-integration, a throwaway integration base). Merge order: #1003 into its base first, then this one repointed.What changes
bin/magento durable:workerdrains the table queues whenresource/durableis declared.--role: one process serves the resume, timer and activity queues.--role=journalserves resumes and timers,--role=activityserves activities.--role=nexusis refused: "The database backend has no Nexus role: Nexus operations need a Temporal cluster. Run durable:worker with --role=journal or --role=activity, or without --role to serve both."SIGTERMandSIGINTend the loop between two messages.DatabaseWorker::tick()takes a message, handles it under the execution lock (resume, timer) or the core processor's attempt claim (activity), and acknowledges it once handled.TableQueue::release()(oneUPDATE, token-checked likeack()), delivered again after 0.5 s. The message is never acknowledged on those paths.holds()on the execution lock is asked before each resume or timer handler. For activities the claim is held byActivityMessageProcessorfor the whole attempt; the worker has no hook inside the activity to ask again (see below).The bench's minimal
drain.phpis replaced bymagento/tests/worker.php, which runs the real command in its own process.Tests
Bench, against MySQL 8.0 (
magento/phpunit.xml.dist):LOCK TABLESfrom a second connection,lock_wait_timeout = 1) leaves the resume in the queue, and it is handled once the lock is gone;kill -9ed inside the activity, the queue still holds the message, the server has freed the attempt claim, and a second worker finishes the run with oneActivityCompleted. The lease (600 s by default) is brought to its end with anUPDATEinstead of being waited for;SIGTERMmakes the worker exit 0 with "stopped by a signal".Root suite: the role refusals, with the messages above.
Not done here
durable_*tables: the bench test above checks the second point (getTables('durable\_%')on the shop's connection is empty) and uses a second database on one server, not a second server.holds()inside the activity, as described above.