laravelqueuejobMahir3 mnt baca

Queue dan Job: Kerja di Background

Pindahkan kerja berat ke background dengan job, driver database/redis, dan handling gagal.

Kenapa butuh queue?

Kirim email, resize gambar, hit API pihak ketiga, atau generate laporan: semua ini lambat kalau dikerjakan saat user menunggu response. Queue memindahkan kerja itu ke background, response kembali dalam milidetik.

Membuat dan menjalankan job

bash
php artisan make:job KirimEmailSelamatDatang
php
// app/Jobs/KirimEmailSelamatDatang.php
namespace App\Jobs;

use App\Models\User;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;

class KirimEmailSelamatDatang implements ShouldQueue
{
    use Queueable;

    public function __construct(public User $user) {}

    public function handle(): void
    {
        // kerja berat di sini, misal kirim email
        Mail::to($this->user->email)->send(new SelamatDatang($this->user));
    }
}

// Dispatch dari controller: langsung kembali, tidak menunggu
KirimEmailSelamatDatang::dispatch($user);

// Atau tunda 10 menit
KirimEmailSelamatDatang::dispatch($user)->delay(now()->addMinutes(10));

Driver queue

bash
# .env
QUEUE_CONNECTION=database

Driver sync (default) menjalankan job langsung, cocok untuk development tapi tidak ada efek background. Driver database menyimpan job di tabel jobs (buat tabelnya dengan php artisan queue:table lalu migrate). Untuk production serius pakai redis.

Jalankan worker yang memproses antrean:

bash
php artisan queue:work

Di production, worker harus jalan terus via Supervisor atau systemd, bukan manual di terminal.

Job gagal dan retry

php
class KirimEmailSelamatDatang implements ShouldQueue
{
    public int $tries = 3;          // coba maksimal 3x
    public int $backoff = 60;       // jeda 60 detik antar percobaan

    public function failed(\Throwable $e): void
    {
        // catat ke log atau beri tahu admin
        Log::error('Job gagal: '.$e->getMessage());
    }
}

Job yang gagal total masuk ke tabel failed_jobs. Coba lagi dengan php artisan queue:retry all atau hapus dengan queue:flush.

Catatan teknis: Jangan dispatch job yang membawa model dengan relasi yang belum di-load lalu mengaksesnya di handle() tanpa me-load ulang. Model di-serialize ulang saat job dijalankan worker, dan state relasinya tidak ikut. Pola aman: kirim ID saja, lalu query ulang di dalam handle().