# Queues & Background Jobs This template includes Redis-powered queues for background processing. ## Quick Start ```bash # Start queue worker make queue-start # View queue logs make queue-logs # Stop queue worker make queue-stop # Restart after code changes make queue-restart ``` ## Configuration Queue is configured to use Redis in `.env`: ```env QUEUE_CONNECTION=redis REDIS_HOST=redis REDIS_PORT=6379 ``` ## Creating Jobs ```bash php artisan make:job ProcessOrder ``` ```php order->update(['status' => 'processing']); // Send notification, generate invoice, etc. } public function failed(\Throwable $exception): void { // Handle failure - log, notify admin, etc. logger()->error('Order processing failed', [ 'order_id' => $this->order->id, 'error' => $exception->getMessage(), ]); } } ``` ## Dispatching Jobs ```php // Dispatch immediately to queue ProcessOrder::dispatch($order); // Dispatch with delay ProcessOrder::dispatch($order)->delay(now()->addMinutes(5)); // Dispatch to specific queue ProcessOrder::dispatch($order)->onQueue('orders'); // Dispatch after response sent ProcessOrder::dispatchAfterResponse($order); // Chain jobs Bus::chain([ new ProcessOrder($order), new SendOrderConfirmation($order), new NotifyWarehouse($order), ])->dispatch(); ``` ## Job Queues Use different queues for different priorities: ```php // High priority ProcessPayment::dispatch($payment)->onQueue('high'); // Default SendEmail::dispatch($email)->onQueue('default'); // Low priority GenerateReport::dispatch($report)->onQueue('low'); ``` Run workers for specific queues: ```bash # Process high priority first php artisan queue:work --queue=high,default,low ``` ## Scheduled Jobs Add to `app/Console/Kernel.php` or `routes/console.php`: ```php // routes/console.php (Laravel 11+) use Illuminate\Support\Facades\Schedule; Schedule::job(new CleanupOldRecords)->daily(); Schedule::job(new SendDailyReport)->dailyAt('08:00'); Schedule::job(new ProcessPendingOrders)->everyFiveMinutes(); // With queue Schedule::job(new GenerateBackup)->daily()->onQueue('backups'); ``` Start scheduler: ```bash make scheduler-start ``` ## Module Jobs When creating module jobs, place them in the module's directory: ``` app/Modules/Inventory/ ├── Jobs/ │ ├── SyncStock.php │ └── GenerateInventoryReport.php ``` ```php order->id), ]; } } ``` ## Monitoring ### View Failed Jobs ```bash php artisan queue:failed ``` ### Retry Failed Jobs ```bash # Retry specific job php artisan queue:retry # Retry all failed jobs php artisan queue:retry all ``` ### Clear Failed Jobs ```bash php artisan queue:flush ``` ## Production Setup For production, use Supervisor instead of Docker: ```ini # /etc/supervisor/conf.d/laravel-worker.conf [program:laravel-worker] process_name=%(program_name)s_%(process_num)02d command=php /var/www/html/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600 autostart=true autorestart=true stopasgroup=true killasgroup=true user=www-data numprocs=2 redirect_stderr=true stdout_logfile=/var/www/html/storage/logs/worker.log stopwaitsecs=3600 ``` ```bash sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start laravel-worker:* ``` ## Testing Jobs ```php use Illuminate\Support\Facades\Queue; it('dispatches order processing job', function () { Queue::fake(); $order = Order::factory()->create(); // Trigger action that dispatches job $order->markAsPaid(); Queue::assertPushed(ProcessOrder::class, function ($job) use ($order) { return $job->order->id === $order->id; }); }); it('processes order correctly', function () { $order = Order::factory()->create(['status' => 'pending']); // Run job synchronously (new ProcessOrder($order))->handle(); expect($order->fresh()->status)->toBe('processing'); }); ```