1. High-Level Architecture
The Zero CMS Job Queue Module provides a robust, zero-dependency, lightweight background task manager. Unlike heavy enterprise frameworks (such as Laravel) that rely on complex object serialization and continuous memory-hogging daemons, Zero CMS uses stateless JSON-based job payloads and transactional double-locking to ensure maximum concurrency speed, security, and absolute tenant isolation.
2. Database Column Schema
Background tasks are persisted inside the queue_jobs database table. This table tracks the fully qualified class name (FQN) of the job handler, serialized parameters, current execution attempts, locks, failures, and traceback logs:
CREATE TABLE queue_jobs (
id VARCHAR(36) PRIMARY KEY,
site_id VARCHAR(36) NOT NULL,
job_class VARCHAR(255) NOT NULL,
payload JSON NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
attempts INT DEFAULT 0,
reserved_at DATETIME NULL,
failed_at DATETIME NULL,
error_message TEXT NULL
);3. Concurrency Race & Deadlock Prevention
To guarantee that two parallel worker threads never process the same background job concurrently, the Queue Runner implements a double-locking race safety protocol inside a strict database transaction:
- Row-Locking Selection: Uses
FOR UPDATEto lock the oldest pending job row:SELECT id FROM queue_jobs WHERE status = 'pending' LIMIT 1 FOR UPDATE; - State Transition Update: Immediately updates the row status to
'reserved'and increments attempts before committing:UPDATE queue_jobs SET status = 'reserved' WHERE id = ?; - Commit Lock Release: Commits the transaction to release the row lock for other workers while keeping the job marked as reserved.
4. Dual Execution Runners
To support all hosting environments, the module features two execution models:
- CLI Daemon Worker: A lightweight console command loop that polls and processes the queue via background terminal threads (ideal for VPS/dedicated servers).
- Async Web Webhook Trigger: A fire-and-forget fallback that triggers the queue processor using raw socket handshakes (
fsockopen) dynamically during standard client web requests, avoiding any client-side execution delay (ideal for shared hosting without cron access).