Checklist review queue worker agar patch AI tidak merusak operasi harus dimulai dari asumsi yang sederhana: kode hasil AI bisa terlihat masuk akal sambil tetap salah pada kondisi produksi. Pada sistem queue, kesalahan kecil seperti visibility timeout yang tidak cocok, retry tanpa batas, atau lock yang tidak pernah dilepas dapat berubah menjadi backlog, duplicate processing, atau data tidak konsisten.

Karena itu, review perubahan yang dibantu AI tidak cukup berhenti pada "tes lolos" atau "kode tampak bersih". Untuk komponen seperti queue, worker, cache, locking, dan consistency, tim perlu mengaudit failure mode nyata, indikator observabilitas, dan strategi rollout. Prinsipnya dekat dengan pengingat know thine enemy: perlakukan patch AI sebagai sesuatu yang wajib diverifikasi, bukan dipercaya mentah.

Prinsip operasional: asumsi default pada patch AI adalah berisiko sampai terbukti aman. Fokus review bukan hanya benar secara sintaks, tetapi aman saat jaringan lambat, worker restart, message terproses ulang, cache tertinggal, dan event datang tidak berurutan.

Ruang lingkup review sebelum rilis

Untuk patch di area queue dan worker, review sebaiknya menjawab lima pertanyaan utama:

  1. Apa yang terjadi jika job diproses lebih dari sekali?
  2. Apa yang terjadi jika job gagal berkali-kali atau timeout?
  3. Apa yang terjadi jika urutan event berubah?
  4. Apa yang terjadi jika cache atau lock tidak sinkron dengan state database?
  5. Bagaimana tim tahu masalah sedang terjadi sebelum pelanggan melapor?

Jika review tidak menjawab lima hal itu, patch belum siap untuk sistem produksi yang bergantung pada queue.

Checklist review inti untuk queue worker

1. Kontrak delivery: at-least-once berarti duplicate adalah normal

Banyak sistem queue bekerja dengan semantik at-least-once delivery. Artinya job bisa diterima lebih dari sekali karena worker crash setelah side effect terjadi tetapi sebelum acknowledgement berhasil. Patch AI sering gagal menangkap fakta ini, lalu menulis handler yang mengasumsikan eksekusi tunggal.

Pertanyaan audit:

  • Apakah handler job aman jika pesan yang sama diproses dua kali?
  • Apakah ada operasi yang menulis ke database, memanggil API eksternal, mengirim email, atau memotong saldo tanpa proteksi idempotensi?
  • Apakah deduplikasi dilakukan berdasarkan kunci bisnis yang stabil, bukan berdasarkan timestamp acak?

Gejala di produksi:

  • Order terbayar dua kali.
  • Email atau notifikasi terkirim ganda.
  • Row duplikat muncul setelah redeploy atau worker restart.

Yang harus dicek di patch:

  • Adanya idempotency key yang konsisten per operasi.
  • Constraint database yang mencegah duplikasi saat memungkinkan.
  • Side effect eksternal dibungkus dengan pengecekan status atau tabel jejak proses.
-- Contoh ide proteksi di database: satu event bisnis hanya boleh diproses sekali
CREATE TABLE processed_events (
  event_id VARCHAR(128) PRIMARY KEY,
  processed_at TIMESTAMP NOT NULL
);

-- Alur worker:
-- 1. INSERT event_id
-- 2. Jika gagal karena sudah ada, anggap duplicate dan hentikan aman
-- 3. Jalankan side effect hanya setelah insert berhasil

Pendekatan ini bekerja karena database menjadi sumber kebenaran untuk deduplikasi. Trade-off-nya adalah ada penulisan tambahan dan desain kunci event harus stabil.

2. Retry policy: cegah retry storm

Retry adalah kebutuhan normal. Yang berbahaya adalah retry yang tidak dibatasi, tidak memakai backoff, atau ikut memproses error permanen seperti validasi salah. Patch AI sering menambahkan retry umum untuk semua error tanpa klasifikasi.

Pertanyaan audit:

  • Error mana yang transient dan layak di-retry?
  • Error mana yang permanen dan harus langsung dipindah ke dead-letter queue atau status gagal final?
  • Apakah ada jitter atau backoff eksponensial untuk mencegah serangan serentak ke dependency yang sedang lambat?

Gejala di produksi:

  • Lonjakan drastis pada jumlah attempt per job.
  • Dependency eksternal makin jatuh karena dibombardir retry.
  • Backlog terus naik walaupun worker autoscaling ditambah.

Checklist:

  • Pastikan retry memiliki batas maksimal attempt.
  • Gunakan backoff bertingkat, bukan retry instan terus-menerus.
  • Jangan retry error logika bisnis yang tidak akan membaik dengan waktu.
  • Pisahkan metrik antara first attempt failure dan retry success.
// Pseudocode klasifikasi error
try {
  process(job)
} catch (err) {
  if (isPermanentBusinessError(err)) {
    moveToDeadLetter(job, err)
  } else if (isTransient(err)) {
    retryWithBackoff(job)
  } else {
    markFailed(job, err)
  }
}

Jika patch AI tidak membedakan jenis error, hampir pasti review harus meminta revisi.

3. Visibility timeout dan durasi kerja harus selaras

Visibility timeout yang terlalu pendek membuat job muncul lagi sebelum worker pertama selesai, sehingga dua worker memproses payload yang sama. Ini salah satu penyebab duplicate job yang sering luput karena tes lokal biasanya terlalu cepat.

Pertanyaan audit:

  • Berapa durasi normal dan puncak pemrosesan job?
  • Apakah timeout queue lebih besar dari waktu kerja realistis, termasuk latensi dependency eksternal?
  • Apakah worker memperpanjang lease untuk job panjang bila platform mendukung?

Gejala di produksi:

  • Job yang sama diproses paralel oleh dua worker.
  • Log menunjukkan pemrosesan sukses, tetapi queue tetap memunculkan ulang pesan yang sama.
  • Puncak duplicate terjadi saat dependency lambat.

Checklist:

  • Samakan asumsi antara timeout worker, timeout HTTP client, dan visibility timeout queue.
  • Jangan set timeout berdasarkan rata-rata; gunakan margin untuk skenario lambat.
  • Pastikan shutdown worker menangani job in-flight dengan benar.

Kesalahan umum patch AI adalah menurunkan timeout agar "lebih responsif" tanpa memahami efeknya pada redelivery.

4. Idempotency harus eksplisit, bukan implisit

Idempotensi yang kuat bukan berarti fungsi tampak aman, tetapi berarti hasil akhir tetap benar saat request atau job diulang. Patch AI sering mengandalkan pengecekan seperti "jika status belum sukses maka proses", padahal race condition masih bisa terjadi.

Pertanyaan audit:

  • Di mana kunci idempotensi disimpan?
  • Apakah pengecekan dan penandaan proses terjadi atomik?
  • Apakah panggilan ke payment gateway, email provider, atau inventory service punya mekanisme dedupe sendiri?

Contoh rawan:

// Rawan race condition
if (!paymentAlreadyCaptured(orderId)) {
  capturePayment(orderId)
  markPaymentCaptured(orderId)
}

Jika dua worker masuk bersamaan, keduanya bisa lolos dari pengecekan pertama. Lebih aman bila ada constraint unik atau transaksi dengan kunci bisnis yang jelas.

5. Cache: validasi stale read dan invalidation

Patch AI sering menambahkan cache untuk mengurangi beban database, tetapi gagal menyesuaikan invalidation dengan pola update asinkron. Pada sistem queue, stale cache bisa membuat worker mengambil keputusan dari state yang sudah usang.

Pertanyaan audit:

  • Apakah worker membaca cache sebagai sumber kebenaran, atau hanya optimisasi?
  • Kapan cache dihapus atau diperbarui setelah job sukses, gagal, atau di-retry?
  • Apakah TTL cache cukup pendek untuk data yang sensitif terhadap ordering?

Gejala di produksi:

  • Status order bolak-balik antara lama dan baru.
  • Worker melewatkan proses karena cache bilang status sudah final.
  • API pengguna menampilkan data berbeda dari database.

Checklist:

  • Jangan gunakan cache untuk guard logic kritis tanpa fallback yang aman.
  • Review apakah invalidation terjadi di semua jalur: sukses, gagal, timeout, kompensasi.
  • Untuk data kritis, lebih aman baca dari database lalu gunakan cache hanya untuk respon baca eksternal.

6. Distributed lock: pastikan tidak bocor atau salah cakupan

Lock terdistribusi sering dipakai untuk mencegah eksekusi ganda. Masalahnya, patch AI sering menambahkan lock generik tanpa memikirkan ownership, expiry, dan pelepasan lock saat proses mati di tengah jalan.

Pertanyaan audit:

  • Apa kunci lock-nya? Apakah terlalu kasar sehingga menurunkan throughput, atau terlalu sempit sehingga tidak mencegah race?
  • Apakah lock punya TTL?
  • Apakah hanya pemilik lock yang boleh melepaskannya?
  • Apa yang terjadi jika proses crash setelah memperoleh lock?

Gejala di produksi:

  • Job macet karena lock tidak pernah lepas.
  • Throughput turun karena semua item antre pada satu lock global.
  • Duplicate tetap terjadi karena TTL lock lebih pendek dari waktu kerja.

Checklist:

  • Gunakan lock per entitas bisnis bila memungkinkan, misalnya per order atau per customer.
  • Set TTL lock sesuai durasi kerja realistis.
  • Hindari asumsi bahwa lock saja menyelesaikan idempotensi; tetap butuh proteksi di data layer.
// Pseudocode lock dengan token kepemilikan
lockToken = acquireLock("order:" + orderId, ttl=120)
if (!lockToken) return retryLater()

try {
  processOrder(orderId)
} finally {
  releaseLockIfOwner("order:" + orderId, lockToken)
}

Pelepasan berdasarkan token pemilik penting untuk mencegah worker lain menghapus lock yang bukan miliknya.

7. Out-of-order event: urutan tidak boleh diasumsikan selalu benar

Pada sistem event-driven, event bisa datang terlambat atau tidak berurutan. Patch AI sering menulis handler yang selalu menganggap event terbaru datang terakhir, padahal kenyataannya event cancelled bisa tiba sebelum paid, atau event lama muncul ulang setelah retry.

Pertanyaan audit:

  • Apakah event memiliki versi, sequence, atau timestamp sumber yang dapat diverifikasi?
  • Apakah handler memeriksa apakah event lebih lama dari state saat ini?
  • Apakah ada aturan merge atau conflict resolution yang eksplisit?

Gejala di produksi:

  • Status entitas mundur ke state lama.
  • Data audit menunjukkan transisi status yang tidak mungkin.
  • Bug hanya muncul saat traffic tinggi atau saat replay event.

Checklist:

  • Simpan versi atau sequence terakhir yang sudah diproses per entitas.
  • Tolak atau abaikan event yang lebih tua dari state terkini jika model bisnis memungkinkan.
  • Uji replay dan delayed delivery sebelum rilis.

8. Backlog tak teramati: queue sehat harus bisa dilihat, bukan diasumsikan

Patch AI bisa lolos review karena benar secara fungsional, tetapi tetap menyebabkan backlog yang tak terlihat. Sistem queue yang tidak punya observabilitas memadai akan memberi tahu tim terlalu terlambat.

Pertanyaan audit:

  • Metrik apa yang menunjukkan queue menumpuk?
  • Apakah ada alert untuk oldest message age, failure rate, dan dead-letter growth?
  • Bisakah tim membedakan bottleneck di enqueue, dequeue, atau dependency eksternal?

Gejala di produksi:

  • Pelanggan melihat update lambat, tetapi dashboard aplikasi terlihat normal.
  • CPU worker rendah namun antrean terus bertambah karena lock contention atau dependency timeout.
  • Dead-letter queue tumbuh tanpa alert.

Metrik dan alert minimum yang wajib ada

Untuk mencegah patch AI merusak operasi secara diam-diam, berikut metrik minimum yang sebaiknya dipantau:

  • Queue depth: jumlah item dalam antrean per jenis job.
  • Oldest message age: umur pesan tertua; ini sering lebih berguna daripada sekadar depth.
  • Processing latency: waktu dari enqueue sampai sukses diproses.
  • Attempt count distribution: apakah banyak job butuh banyak retry.
  • Success/failure rate per worker dan per job type.
  • Dead-letter queue size dan laju pertumbuhannya.
  • Duplicate detection count: berapa banyak job ditolak karena idempotency.
  • Lock acquisition failure rate dan lock wait time.
  • Cache hit ratio untuk konteks performa, tetapi jangan dijadikan satu-satunya indikator kesehatan.
  • Dependency latency/error rate untuk API, database, dan cache store.

Alert yang berguna:

  • Oldest message age melewati SLA tertentu.
  • Failure rate naik bersamaan dengan retry rate.
  • Dead-letter queue bertambah terus dalam periode singkat.
  • Durasi job mendekati atau melampaui visibility timeout.
  • Duplicate protection aktif jauh lebih sering dari baseline normal.

Kesalahan umum adalah hanya memonitor CPU dan memory worker. Pada banyak insiden queue, resource host terlihat sehat sementara backlog sebenarnya tidak tertangani.

Pertanyaan audit saat review patch AI

Gunakan daftar ini saat code review, design review, atau pre-release checklist:

  1. Apa invariannya? Misalnya: pembayaran tidak boleh tercapture dua kali, status tidak boleh mundur, satu order hanya punya satu final state.
  2. Apa side effect eksternalnya? Email, pembayaran, inventory, webhook, cache invalidation.
  3. Bagaimana perilaku saat job diproses ulang?
  4. Bagaimana perilaku saat worker mati setelah side effect tetapi sebelum ack?
  5. Bagaimana perilaku saat dependency timeout?
  6. Apakah retry dibatasi dan diklasifikasi?
  7. Apakah lock diperlukan, dan apakah lock cukup aman?
  8. Apakah state dibaca dari sumber yang tepat, bukan cache stale?
  9. Apakah urutan event diasumsikan padahal tidak dijamin?
  10. Alert apa yang akan menyala jika patch ini salah?

Review yang baik bukan bertanya “apakah ini jalan?”, tetapi “bagaimana ini gagal di produksi, dan apakah kita siap mendeteksinya?”

Contoh skenario review patch yang tampak aman tetapi berbahaya

Kasus: AI menambahkan cache dan lock pada worker pemroses order

Patch terlihat seperti perbaikan performa: baca status order dari cache, ambil lock global, proses pembayaran, lalu update database. Sekilas rapi. Risiko nyatanya:

  • Cache stale: worker melihat status pending padahal order sudah dibatalkan.
  • Lock global: seluruh throughput turun karena semua order antre pada satu kunci.
  • TTL lock pendek: lock habis saat payment API lambat, lalu worker kedua masuk.
  • No idempotency: pembayaran tercapture ganda.
  • Retry semua error: validation error ikut diulang dan memenuhi antrean.

Pada review, solusi bukan sekadar mengubah gaya kode. Yang perlu diperbaiki adalah model operasionalnya:

  • Pakai lock per order, bukan lock global.
  • Gunakan idempotency key pada operasi pembayaran.
  • Jadikan database sumber state final untuk guard logic kritis.
  • Klasifikasikan error sebelum retry.
  • Tambahkan metrik untuk duplicate, retry, dan age of oldest message.

Strategi testing yang relevan untuk patch queue

Tes unit saja tidak cukup. Untuk area ini, minimal lakukan kombinasi berikut:

1. Test idempotency

Jalankan handler dua kali dengan payload yang sama dan pastikan side effect final tetap satu kali.

2. Test retry dan timeout

Simulasikan dependency lambat atau gagal sementara. Verifikasi retry terjadi sesuai kebijakan, bukan tanpa batas.

3. Test crash window

Simulasikan proses berhenti setelah side effect berhasil tetapi sebelum ack atau status tersimpan. Ini penting untuk menemukan duplicate processing.

4. Test out-of-order delivery

Kirim event versi baru lalu event lama. Pastikan state tidak mundur.

5. Test stale cache

Isi cache dengan data lama, ubah state di database, lalu jalankan worker. Pastikan keputusan kritis tidak bergantung buta pada cache.

6. Test concurrency

Jalankan dua worker pada entitas yang sama untuk memvalidasi lock, transaction boundary, dan unique constraint.

Langkah rollout aman untuk perubahan queue worker

Walaupun review sudah ketat, patch AI tetap sebaiknya dirilis secara bertahap.

  1. Gunakan feature flag atau routing terbatas
    Arahkan sebagian kecil job type atau tenant ke worker baru lebih dulu.
  2. Aktifkan shadow metrics
    Tambahkan metrik baru sebelum trafik penuh, supaya baseline lama dan perilaku baru bisa dibandingkan.
  3. Persempit blast radius
    Mulai dari queue sekunder atau job non-kritis jika arsitektur memungkinkan.
  4. Siapkan rollback cepat
    Pastikan deploy worker bisa dibalik tanpa migrasi state yang memaksa.
  5. Monitor window pasca-rilis
    Amati queue depth, oldest message age, retry rate, dead-letter, duplicate detection, dan dependency latency.
  6. Freeze perubahan lain saat observasi awal
    Agar sinyal insiden tidak tertutup perubahan yang tidak terkait.

Catatan penting: rollback kode belum tentu menghapus dampak side effect yang sudah terjadi. Untuk patch di area pembayaran, inventory, atau status final, siapkan juga prosedur kompensasi data.

Checklist singkat yang bisa dipakai tim produksi

  • Handler aman terhadap duplicate processing.
  • Ada idempotency key atau unique constraint untuk operasi kritis.
  • Retry dibatasi, pakai backoff, dan hanya untuk error transient.
  • Visibility timeout sesuai durasi kerja realistis.
  • Worker shutdown dan crash tidak meninggalkan state setengah jalan tanpa penanganan.
  • Cache tidak dipakai sebagai sumber kebenaran untuk guard logic kritis.
  • Distributed lock punya TTL, ownership, dan cakupan yang tepat.
  • Out-of-order event ditangani dengan versioning atau sequence check.
  • Queue depth, oldest age, failure rate, retry rate, dan DLQ dimonitor.
  • Rollout dilakukan bertahap dengan rollback dan kompensasi yang jelas.

Penutup

Checklist review queue worker agar patch AI tidak merusak operasi bukan soal anti-AI, tetapi soal disiplin produksi. Pada sistem asinkron, bug yang paling mahal biasanya bukan bug yang membuat aplikasi langsung error, melainkan bug yang diam-diam memproses ulang, mengunci state, menimbulkan backlog, atau membuat data tidak konsisten.

Karena itu, gunakan patch AI sebagai bahan awal, bukan jawaban final. Review-lah dengan pola pikir operasional: cari duplicate job, retry storm, visibility timeout yang salah, idempotency lemah, cache stale, lock bocor, event tidak berurutan, dan backlog yang tak teramati. Jika tim bisa menjawab failure mode itu sebelum rilis, kemungkinan besar patch akan jauh lebih aman saat bertemu kondisi produksi yang nyata.