Menjawab langsung masalah CodeIgniter 4 Debugging Job Queue API Gagal karena Cache Session

Job queue API di CodeIgniter 4 mengalami kegagalan berulang (timeout, response error, pekerjaan ganda) saat memproses payload user. Penyebab utama adalah inkonsistensi konfigurasi session dan cache antara proses HTTP biasa dan worker queue, yang membuat worker tidak bisa membaca session token sekaligus memicu duplikasi job. Artikel ini menjelaskan gejala, log observasi, konfigurasi, langkah debugging, serta perbaikan yang langsung dapat diterapkan.

Gejala API Job Queue Gagal dan Observasi Log

Gejala yang muncul pada sistem produksi

Ketika job queue API di-trigger oleh endpoint /api/v1/jobs/dispatch, respons client sering berakhir timeout 504, sedangkan job worker terus memproses ulang data yang sama. Gejala nyata:

  • Client menerima 504 Gateway Timeout atau 500 Internal Server Error.
  • Log menunjukkan job worker memulai ulang job dengan data identik dalam waktu singkat (duplikasi).
  • Payload job tetap di queue meskipun sudah selesai—menandakan ack tidak pernah terjadi.

Cuplikan log yang mengindikasikan cache/session issue

2024-xx-xx 11:42:10 ERROR /worker/job QueueWorker: Timeout membaca session token untuk job_id=1234 (cacheMiss)
2024-xx-xx 11:42:11 WARN /worker/job QueueWorker: Job barang:update ditarik ulang (attempt=3) karena response "SessionMismatchException"
2024-xx-xx 11:42:11 INFO /worker/job QueueWorker: Job enqueue ulang untuk payload user_id=98

Log menyiratkan bahwa worker tidak bisa mengakses session token (dipicu cache miss), sehingga job dianggap gagal sebelum melakukan ack. API queue menunggu respon worker dan akhirnya timeout.

Monitoring dan Langkah Reproduksi

Monitoring yang digunakan

Gunakan kombinasi:
- CI logger dengan level DEBUG di app/Config/Logger.php untuk job queue.
- Redis monitor (redis-cli monitor) untuk melihat enqueue/dequeue aktivitas.
- Grafana untuk metrik worker (job duration, failure count) melalui exporter Prometheus dari worker container.

Langkah reproduksi kegagalan

  1. Trigger API queue dengan payload berisi user yang memiliki session aktif.
  2. Amati job worker melalui log dan Redis monitor—perhatikan jika job gagal menghapus key session.
  3. Reproduksi cukup konsisten setelah deploy konfig cache baru (contoh: session driver default file sementara worker menggunakan RedisHandler manual).

Root Cause: Cache Session dan Worker Tidak Sinkron

Masalah utamanya adalah worker queue berjalan dalam container terpisah yang tidak menggunakan cache/session provider yang sama dengan proses HTTP API:

  • Session disimpan di app/Config/App.php menggunakan driver CodeIgniter\Session\Handlers\FileHandler.
  • Job worker yang dijalankan via php spark queue:work dikonfigurasi manual untuk membaca session via RedisHandler yang spesifik ke container lain.

Konsistensi ini diperlukan karena job queue API mengandalkan session token user untuk validasi. Worker tidak bisa memvalidasi job tanpa session token, menyebabkan ack tidak pernah terjadi dan job digulung ulang. Cache session lalu dianggap hilang, memicu error yang terlihat di log.

Konfigurasi Session/Cache Sebelum dan Sesudah Perbaikan

Berikut konfigurasi session/cache sebelum perbaikan yang menyebabkan inkonsistensi.

// app/Config/App.php
public $sessionDriver = 'CodeIgniter\Session\Handlers\FileHandler';
public $sessionSavePath = WRITEPATH . 'session';
public $sessionCookieName = 'ci_session';

// worker config (di config/queue.php custom)
'cacheDriver' => 'redis',
'cachePrefix' => 'worker_',
'redis' => [
    'host' => 'redis-worker',
    'port' => 6379,
]

Setelah perbaikan, worker dan HTTP API menggunakan driver cache/session yang sama serta sinkron host port.

// app/Config/App.php (disinkronisasi untuk worker)
public $sessionDriver = 'CodeIgniter\Session\Handlers\RedisHandler';
public $sessionSavePath = 'tcp://redis-main:6379';
public $sessionCookieName = 'ci_session';

// config/Queue.php (dipakai worker)
'cacheDriver' => 'redis',
'cachePrefix' => 'job_', // prefix berbeda untuk job queue
'redis' => [
    'host' => 'redis-main',
    'port' => 6379,
    'password' => env('REDIS_PASSWORD', null),
]

Catatan: prefix cache berbeda untuk menghindari bentrokan data job dengan session key.

Langkah Perbaikan Detil

  • Reset Cache/Session: lakukan clear cache & session di Redis dengan perintah redis-cli -h redis-main FLUSHALL (atau hapus namespace spesifik jika multi-tenant).
  • Sinkronisasi Worker: pastikan worker menggunakan env yang sama dengan API (misal .env shared) sehingga sessionDriver dan cacheDriver konsisten.
  • Error Handling: Tambahkan try/catch di job handler untuk meng-handle SessionMismatchException dan membuang job jika token sudah tidak valid.

Contoh snippet handling error di job handler:

try {
    $session = session();
    $token = $session->get('auth_token');
    // proses job
} catch (SessionException $e) {
    log_message('error', "Job {$job->getName()} gagal: {$e->getMessage()}");
    $job->stop(); // tidak enqueue ulang otomatis
}

Verifikasi Pasca-Fix dan Mitigasi

Setelah sinkronisasi, lakukan langkah verifikasi berikut:

  1. Trigger job baru dan pastikan respon API cepat (< 200ms) serta job worker berhasil ack.
  2. Monitor log—tidak ada lagi error SessionMismatchException atau job duplikat.
  3. Gunakan dashboard Redis atau Prometheus untuk memastikan queue depth tidak menanjak.

Sebagai mitigasi jangka panjang:

  • Gunakan shared configuration (env yang sama) antara API dan worker untuk persyaratan cache/session.
  • Tambahkan health check cron job yang memastikan worker dapat mengakses session melalui cache sebelum memproses job.
  • Implementasikan distributed lock jika job sensitif terhadap duplikasi.

Dengan langkah di atas, Anda dapat menyelesaikan masalah debugging job queue API yang gagal akibat cache session tidak konsisten di CodeIgniter 4.