1. Go to this page and download the library: Download deverity/spawn-queue library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
Configure::write('SpawnQueue', [
'poll_interval' => 1, // seconds between polling cycles when idle
'shutdown_timeout' => 30, // seconds to wait for jobs on graceful shutdown
'stuck_job_timeout' => 300, // seconds before a processing job is considered stuck
'stuck_check_interval' => 60, // how often the coordinator checks for stuck jobs
'default_timeout' => 120, // per-job execution timeout (seconds)
'default_max_attempts' => 5,
'connection' => 'default', // CakePHP connection name for all queue DB operations
'show_type' => 'lines', // terminal output: 'lines' (log lines only) or 'tui' (live dashboard only)
'queues' => [
'default' => ['max_workers' => 3, 'timeout' => 120, 'max_attempts' => 5],
'emails' => ['max_workers' => 4, 'timeout' => 60, 'max_attempts' => 5],
'imports' => ['max_workers' => 1, 'timeout' => 1800, 'max_attempts' => 3],
],
]);
use SpawnQueue\Exception\NonRetryableJobException;
use SpawnQueue\Exception\RetryableJobException;
use SpawnQueue\Handler\JobHandlerInterface;
use SpawnQueue\ValueObject\JobData;
use SpawnQueue\Worker\JobResult;
class SendEmailJobHandler implements JobHandlerInterface
{
use \Cake\ORM\Locator\LocatorAwareTrait;
public static function queue(): string
{
return 'emails';
}
public function handle(JobData $job): JobResult
{
$to = $job->payload['to'] ?? null;
if (!$to) {
// Permanent failure — will NOT retry
throw new NonRetryableJobException('Missing "to" in payload');
}
try {
$this->sendEmail($to, $job->payload);
return JobResult::success();
} catch (\RuntimeException $e) {
// Temporary failure — will retry with backoff
throw new RetryableJobException('Transport failed: ' . $e->getMessage());
}
}
}
// This task keeps working exactly as before:
class MyLegacyTask extends \Queue\Queue\Task
{
public function run(array $data, int $jobId): void
{
// your existing code
}
}
// Enqueue it:
QueueService::push(MyLegacyTask::class, $data); // queue defaults to "default"
QueueService::push('default', MyLegacyTask::class, $data); // explicit legacy form