Skip to content

feat(queue): [develop] add pluggable queue API - #7790

Draft
somethingwithproof wants to merge 2 commits into
Cacti:developfrom
somethingwithproof:feat/queue-api
Draft

somethingwithproof wants to merge 2 commits into
Cacti:developfrom
somethingwithproof:feat/queue-api

Conversation

@somethingwithproof

@somethingwithproof somethingwithproof commented Aug 22, 2026 •

Copy link
Copy Markdown
Member

This change adds an opt-in queue API so future Cacti features can hand work to background workers. It includes a database-backed queue, explicit message contracts, routing, leases, retries and administrative commands, with an extension point for provider plugins. This establishes reusable background-work infrastructure; it does not move existing operations onto queues or include the example external-broker integrations.

What this adds

This PR adds a Cacti queue API for durable asynchronous work. Producers publish through stable Cacti functions, handlers are registered by message type, and workers process jobs outside browser requests.

The API provides:

  • a built-in database queue that requires no external broker;
  • independent routing for each named queue, so one installation can use several queue systems at the same time;
  • safe JSON messages with explicit message contracts and no executable callbacks or shell commands;
  • priorities and delayed delivery;
  • visibility leases with renewal for long-running jobs;
  • bounded retries, dead-letter handling, completed-message retention, and administrative health commands;
  • concurrent worker support with atomic message claims; and
  • plugin-defined transports without changing producer or handler code.

Queue systems

The database transport is included. Provider plugins can connect named queues to:

  • RabbitMQ or another AMQP broker;
  • Redis or Redis Streams;
  • Amazon SQS;
  • Apache Kafka adapters; or
  • another provider implementing the queue transport lifecycle.

With suitable provider plugins, an installation could route notifications to RabbitMQ, poller work to SQS, and reports to the built-in database queue. Provider-specific packages and credentials are managed by their provider plugins; those external integrations are not included in this PR.

Operational behavior

The worker and admin CLIs are guarded against web execution. Failed deliveries are retried according to Cacti policy and then moved to a dead-letter state. Workers use reservation tokens and expiring leases so stale workers cannot acknowledge or modify another worker's delivery.

This is dormant infrastructure: it does not migrate existing foreground operations to queues in this PR.

Validation

  • 55 queue unit/MySQL integration tests, 184 assertions; 100% line coverage on PHP 8.3.
  • Two concurrent workers verified against distinct messages by the Docker suite under tests/e2e/queue/.
  • Full unit suite, PHPStan, formatter, translation validation and mandatory commit hooks pass.
  • Broker serialization preserves Cacti delivery policy; malformed policy and oversized payload regressions pass.

Release targeting

  • Target branch: develop
  • Release line: primary development branch; this is not a 1.2.x backport.

Closes #7856

Shares the Symfony Messenger, UID and OptionsResolver requirements with #8012. Existing locked versions are retained except aligning OptionsResolver to 7.4.8.

Release notes are consolidated in #8320. Review and merge this child before that final documentation PR.

Discussion hold

Keep this PR in draft until the maintainer discussion is complete. Agree on the first concrete queue use case, worker operations, delivery semantics and ownership before merging.

Merge order: #8012 first. Both PRs edit composer.json and composer.lock; after #8012 lands, rebase this PR and regenerate only its entries with composer update symfony/messenger symfony/uid --with-dependencies --no-install.

Assigned GitHub milestone: v1.3.0.

Revision and checks

Description scope: target develop, 36 changed files, head 754d91352. Checked 2026-10-23 03:06:04 UTC.

GitHub check snapshot: 2 passed. Local test figures and earlier CI runs above are recorded evidence for their stated revisions and environments; they do not assert that every check passes at this head.

@somethingwithproof
somethingwithproof requested a review from a team as a code owner August 22, 2026 11:12
@somethingwithproof
somethingwithproof requested review from TheWitness and removed request for a team August 22, 2026 11:12
@somethingwithproof somethingwithproof added this to the v1.3.0 milestone Aug 26, 2026
@somethingwithproof somethingwithproof added enhancement General tag for an enhancement api API related issues plugins Plugin related issue database Database and database support issues develop Bug in the development branch php Pull requests that update php code labels Aug 26, 2026
@somethingwithproof somethingwithproof self-assigned this Aug 26, 2026
@somethingwithproof
somethingwithproof marked this pull request as draft August 28, 2026 03:30
@somethingwithproof
somethingwithproof marked this pull request as ready for review August 29, 2026 05:53
@somethingwithproof
somethingwithproof force-pushed the feat/queue-api branch 5 times, most recently from 1a4646d to 57e92e6 Compare August 30, 2026 04:36
@somethingwithproof somethingwithproof added area:api Namespaced Cacti workflow label area:database Namespaced Cacti workflow label area:plugins Namespaced Cacti workflow label release:1.3 Namespaced Cacti workflow label type:enhancement Namespaced Cacti workflow label labels Aug 30, 2026
@somethingwithproof

Copy link
Copy Markdown
Member Author

Force-pushed a rebase onto develop. This branch had picked up six commits that belong to my fork rather than here: the GitHub Actions rewrite (which deleted oldissues.yml and syntax.yml and rewrote dependabot.yml and security.yml), the Composer platform work, the installer DDD foundation, the architecture records, and two ci: commits that only edited a workflow the first of those added. They were the entire source of the conflict and of the 243-commit divergence. Dropped, so the diff is 30 files instead of 81.

I also dropped fix: use the fork database migration helper. It switched queue_messages to db_update_table; the other fifteen tables in 1_3_0.php use db_install_update_table, and it is back on that.

The two real conflicts were in Composer. develop moved symfony to ^7.4, so the new components go there too, and I regenerated the lock rather than hand-merging it: five new entries, no version change to anything already locked.

With the fork workflows gone, three upstream checks ran against this branch for the first time and needed fixes:

  • queue-api-coverage.yml pinned PHP 8.1 against the ^8.2 composer requirement, so pest died in platform_check before running a test. Now 8.2.
  • The sink baseline needed the require_once($queue_autoloader) entry in lib/api_queue.php. It is a constant path off dirname(__DIR__), not input-derived.
  • The CHANGELOG edit had duplicated nine issue entries already on develop and put a feature line inside the issue block. Replaced with a changelog.d/7790.feature fragment.

@somethingwithproof

Copy link
Copy Markdown
Member Author

Reviewed head 74f9769 and submitted follow-up commit efa8a80 to this branch through the GitHub Git API after Git transport stalled. Its tree matches the locally tested commit.

Fixed: malformed stored metadata escaped the dead-letter boundary. Payload decoding was caught, but metadata decoding and correlation-stamp validation happened afterward. A corrupt metadata blob therefore threw from get() while leaving the delivery reserved, repeatedly stopping workers until the lease/attempt limit was exhausted. Metadata and stamp validation now share the existing dead-letter path. The new MySQL regression failed before the fix and now verifies dead-letter status and an idle subsequent receive.

Fixed: the queue E2E fixture selected unsupported PHP 8.2. This branch requires PHP ^8.3. The Compose build now selects PHP 8.3, and verification documentation matches the current workflow and report output.

Validation: 51 queue unit/integration tests (170 assertions) passed on mise-selected PHP 8.5.11 against a disposable MySQL 8.4.11 container. Composer validation, actionlint for the queue workflow, and repository commit hooks passed. Dependencies were installed from this branch's lock with scripts/plugins disabled. The complete producer/worker Compose E2E suite and coverage percentage were not measured in this review. The original PR exposed no CI checks; the pushed patch still needs upstream CI.

@somethingwithproof

Copy link
Copy Markdown
Member Author

Resolved the merge conflicts with develop at f54da33 and pushed merge commit 2999e02.

The Composer lock retains the queue dependencies and develop's dependency changes. Composer regenerated lock metadata without resolving new package versions. Repository guidance retains both the shared-tooling section and develop's new instructions. Both original histories and the malformed-metadata fix are retained.

The installer CLI helpers now check for an argument before reading it; this fixes the three pre-existing errors that blocked the full PHPStan commit check.

Validation: 37 queue unit tests passed on mise-selected PHP 8.5.11; Composer validation and a clean locked installation passed; full PHPStan reported no errors; commit guards, PHP lint, formatting, and static-analysis hooks passed. The database integration suite was not rerun for this dependency/guidance merge. Updated upstream CI still needs to complete.

@somethingwithproof

Copy link
Copy Markdown
Member Author

Resolved the conflict with current develop and pushed merge commit 3977e24 without rewriting branch history. Kept the current Weblate-managed Swedish catalog exactly as upstream instead of overwriting newer translations with older incidental edits from the queue branch. Composer's merged lockfile validates strictly and installs cleanly; all 37 queue unit tests and 3 browser-isolation contracts pass. Full PHPStan reports no errors, PHP CS Fixer changes zero files, and commit guards pass. GitHub will rerun the database transport and queue E2E checks.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread service/cacti-queue@.service Resolved
Comment thread include/global_settings.php Resolved
Comment thread lib/api_queue.php Resolved
Comment thread tests/tools/audit_po.py Resolved
Comment thread .all-contributorsrc Resolved
Comment thread README.md Resolved
Comment thread docs/development/queue-api.md Resolved
@somethingwithproof somethingwithproof changed the title Add pluggable queue API feat(queue): [develop] add pluggable queue API Oct 12, 2026
@somethingwithproof

Copy link
Copy Markdown
Member Author

Addressed the open review findings. Queue API tests now pass 55 cases / 184 assertions with 100% line coverage on PHP 8.3. The Docker test confirms two concurrent workers handle distinct messages. The full unit suite, PHPStan and required commit checks pass.

An alternating five-round local benchmark measured serialization round trips at 14.86 µs before and 17.19 µs after; the additional work preserves broker delivery policy that was previously lost. This is a serializer diagnostic, not worker or database throughput. Keeping the PR in draft for the documented use-case and delivery-semantics discussion.

somethingwithproof added a commit to somethingwithproof/cacti that referenced this pull request Oct 14, 2026
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Comment thread docker/Dockerfile Fixed
@somethingwithproof
somethingwithproof force-pushed the feat/queue-api branch 2 times, most recently from 3485999 to a2757eb Compare October 17, 2026 20:31
Adds a durable queue API built on Symfony Messenger with a database transport, CLI worker and admin entry points, queue settings, and a systemd unit for the worker.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
@sonarqubecloud

Copy link
Copy Markdown

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:api Namespaced Cacti workflow label area:database Namespaced Cacti workflow label area:plugins Namespaced Cacti workflow label area:poller Namespaced Cacti workflow label php Pull requests that update php code release:1.3 Namespaced Cacti workflow label type:enhancement Namespaced Cacti workflow label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add pluggable queue API

5 participants