Skip to main content

Command Palette

Search for a command to run...

Bukan Sekadar Menunggu: Panduan Praktis Sistem Antrean (Queue) dengan Hono dan Redis

Updated
4 min read
Bukan Sekadar Menunggu: Panduan Praktis Sistem Antrean (Queue) dengan Hono dan Redis
A

I am an enthusiastic researcher and developer with a passion for using technology to innovate in business and education.

Dalam pengembangan aplikasi modern, responsivitas adalah segalanya. Namun, seringkali kita dihadapkan pada tugas-tugas yang memakan waktu: memproses video, membuat laporan, atau mengirim ribuan email. Jika kita mengerjakannya secara langsung, pengguna akan terjebak menatap layar loading.

Solusinya bukan await yang lebih lama, melainkan mengubah cara kita berpikir tentang tugas. Inilah panduan praktis untuk memahami dan mengimplementasikan sistem antrean (queue), sebuah pola arsitektur yang memisahkan "permintaan" dari "pekerjaan" menggunakan Hono sebagai pemicu dan Redis sebagai tulang punggungnya.


## Apa Itu Antrean? Analogi Kedai Kopi ☕

Bayangkan Anda adalah barista di kedai kopi yang sibuk.

  • Producer (Kasir): Pelanggan (pengguna) datang dan memesan kopi. Kasir (aplikasi Hono Anda) menerima pesanan, menuliskannya di secangkir kertas, dan menaruhnya di antrean di sebelah mesin espresso. Tugas kasir selesai dengan cepat, dan ia bisa melayani pelanggan berikutnya.

  • Queue (Antrean Cangkir): Ini adalah Redis. Sebuah tempat penampungan pesanan yang bekerja berdasarkan prinsip FIFO (First-In, First-Out). Pesanan pertama yang masuk, yang pertama akan dibuat.

  • Consumer (Barista): Ini adalah proses Worker Anda yang berjalan terpisah. Barista (worker) mengambil satu per satu cangkir dari antrean, membuat kopinya (melakukan tugas berat), lalu menyajikannya.

Dengan sistem ini, kasir tidak pernah terblokir menunggu kopi selesai dibuat. Inilah inti dari pekerjaan asinkron dan decoupling.


## Kapan Anda Mutlak Membutuhkan Antrean? 💡

Gunakan sistem antrean ketika sebuah tugas bersifat:

  1. Lambat (Slow): Proses yang memakan waktu lebih dari beberapa detik.

    • Contoh: Membuat thumbnail video, mengompres file, atau menarik data dari API pihak ketiga yang lambat.
  2. Berat (Resource-Intensive): Proses yang memakan banyak CPU atau Memori, yang jika dijalankan langsung akan mengganggu performa server utama.

    • Contoh: Analisis gambar, pembuatan laporan PDF yang kompleks.
  3. Banyak (Bulk): Tugas yang perlu dilakukan dalam jumlah besar.

    • Contoh: Mengirim email notifikasi ke 10.000 pengguna. Anda tidak mungkin membuat pengguna menunggu sampai semua email terkirim.

## Implementasi Praktis: Hono + Redis dengan BullMQ 🚀

Mari kita buat contoh nyata. Kita akan menggunakan BullMQ, sebuah library antrean yang kuat dan populer untuk lingkungan Node.js/Bun yang menggunakan Redis sebagai backend.

1. Persiapan Proyek

Pastikan Anda memiliki Redis yang sedang berjalan (bisa melalui Docker, atau layanan gratis seperti Upstash).

Bash

# Inisialisasi proyek dan install dependencies
bun init -y
bun add hono bullmq

2. Kode Producer (Aplikasi Hono Anda)

Ini adalah server HTTP yang menerima permintaan dari pengguna dan menambahkannya ke antrean. Buat file index.ts.

TypeScript

// index.ts
import { Hono } from 'hono'
import { Queue } from 'bullmq'

// 1. Koneksi ke Redis sebagai message broker
const redisConnection = {
  host: '127.0.0.1', // Ganti dengan host Redis Anda
  port: 6379,
}

// 2. Buat instance Queue bernama 'email-queue'
const emailQueue = new Queue('email-queue', { connection: redisConnection })

const app = new Hono()

// 3. Endpoint untuk memicu pengiriman email
app.post('/send-welcome-email', async (c) => {
  const { email, name } = await c.req.json()

  if (!email || !name) {
    return c.json({ error: 'Email and name are required' }, 400)
  }

  // 4. Tambahkan tugas ke antrean dengan data yang relevan
  // Tugas ini akan diambil oleh Worker nanti
  const job = await emailQueue.add('send-email-job', { email, name })

  console.log(`Tugas ${job.id} untuk mengirim email ke ${email} telah ditambahkan ke antrean.`)

  // 5. Langsung beri respons ke pengguna, jangan tunggu email terkirim!
  return c.json({
    message: 'Welcome! We are preparing your welcome email.',
    jobId: job.id,
  })
})

export default {
  port: 3000,
  fetch: app.fetch,
}

3. Kode Consumer (Proses Worker Terpisah)

Ini adalah proses yang berjalan di latar belakang untuk mengerjakan tugas. Buat file worker.ts.

TypeScript

// worker.ts
import { Worker } from 'bullmq'

const redisConnection = {
  host: '127.0.0.1', // Pastikan ini sama dengan di Producer
  port: 6379,
}

console.log('Worker sedang berjalan, menunggu tugas...')

// 1. Buat Worker yang "mendengarkan" antrean 'email-queue'
const worker = new Worker('email-queue', async (job) => {
    const { email, name } = job.data

    console.log(`[START] Memproses tugas ${job.id}: Mengirim email ke ${email}`)

    // 2. Simulasi pekerjaan berat (misalnya, koneksi ke SMTP server)
    // Di dunia nyata, di sinilah Anda akan menggunakan library seperti Nodemailer
    await new Promise(resolve => setTimeout(resolve, 5000)) // Tunggu 5 detik

    console.log(`[DONE] Tugas ${job.id}: Email selamat datang berhasil dikirim ke ${name} (${email})`)

    return { status: 'completed' }
  },
  { connection: redisConnection }
)

worker.on('failed', (job, err) => {
  console.error(`Tugas ${job?.id} gagal dengan error: ${err.message}`)
})

4. Menjalankan Semuanya

Anda perlu menjalankan dua proses ini secara terpisah di terminal yang berbeda.

Terminal 1 (Menjalankan Server Hono):

Bash

bun run index.ts

Terminal 2 (Menjalankan Worker):

Bash

bun run worker.ts

Sekarang, coba kirim permintaan POST ke http://localhost:3000/send-welcome-email dengan body JSON {"email": "test@example.com", "name": "Budi"}. Anda akan langsung mendapatkan respons, dan 5 detik kemudian, Anda akan melihat log "Email berhasil dikirim" di terminal worker.


## Pertimbangan untuk Serverless (Vercel, Cloudflare Workers)

  • Broker (Redis): Anda tidak bisa menjalankan Redis di platform serverless. Anda harus menggunakan layanan terkelola seperti Upstash yang menyediakan URL koneksi Redis.

  • Consumer (Worker): Platform serverless memiliki batas waktu eksekusi. Ini cocok untuk tugas antrean yang cepat (misalnya, beberapa detik), tetapi tidak untuk proses yang memakan waktu berjam-jam. Untuk tugas yang sangat lama, worker Anda sebaiknya dijalankan di lingkungan yang persisten seperti VM (EC2/DigitalOcean) atau kontainer (Fargate/Cloud Run).

More from this blog

F

Finlup ID | Sharing dunia teknologi dan coding

206 posts

Membedah Tren dan Teknologi yang Mengubah Dunia.