queued
- Bintang
- 310
- Dependensi
- 1
- Ukuran
- 2.1k LOC
Antrean kerja yang disimpan di SQLite. Untuk tim yang butuh antrean andal tapi tidak ingin merawat broker terpisah.
Mengapa SQLite
Kebanyakan proyek tidak butuh Kafka. Mereka butuh “jalankan ini nanti, dan jangan hilang kalau proses mati”. SQLite sudah menyelesaikan bagian persistensi dan konkurensi dengan baik, dan satu berkas jauh lebih mudah dicadangkan.
q, err := queued.Open("jobs.db")
if err != nil {
log.Fatal(err)
}
// Enqueue di dalam transaksi yang sama dengan pekerjaan utama,
// sehingga keduanya komit atau gagal bersamaan.
err = q.Enqueue(ctx, tx, "resize", ResizePayload{ID: 42, Width: 800})Bagian yang menarik adalah Enqueue menerima transaksi. Pekerjaan dan
penjadwalannya komit bersamaan — tidak ada keadaan di mana data ada tapi
pekerjaannya tidak tercatat.
Konkurensi
Klaim pekerjaan memakai UPDATE ... RETURNING dalam transaksi BEGIN IMMEDIATE, sehingga dua worker tidak pernah mengambil pekerjaan yang sama:
UPDATE jobs
SET state = 'running', claimed_at = ?
WHERE id = (
SELECT id FROM jobs
WHERE state = 'pending' AND run_at <= ?
ORDER BY run_at
LIMIT 1
)
RETURNING id, kind, payload;Yang saya pelajari
Menulis ulang ini tiga kali. Versi pertama memakai tabel terpisah per status, versi kedua memakai polling tanpa indeks. Keduanya gagal pada beban uji yang sama: banyak worker, sedikit pekerjaan.