Penjadwalan yang kita kuasai sepanjang section ini menjawab pertanyaan “kapan data biasanya tiba” — pesanan menumpuk lalu diproses pukul 06:00, apa pun yang terjadi. Banyak kebutuhan bisnis tidak sabar dengan asumsi tersebut: dashboard operasional harus memperbarui angka beberapa menit setelah berkas mitra diunggah, sistem deteksi penipuan harus bereaksi begitu transaksi mencurigakan tiba. Pola event-driven mengganti pertanyaannya menjadi “apa yang harus dipicu segera setelah kejadian tertentu terjadi”. Bab ini membedah pola pemicunya, mensimulasikan dispatcher event dengan Python murni, lalu menimbang trade-off yang menyertainya.
Pemicu Jadwal versus Pemicu Event #
| Aspek | Terjadwal | Event-driven |
|---|---|---|
| Pemicu | waktu — cron atau interval | kejadian — berkas, pesan, panggilan API |
| Latensi khas | puluhan menit sampai jam | detik sampai menit |
| Kompleksitas infrastruktur | rendah: scheduler saja | lebih tinggi: butuh sensor, queue, atau endpoint |
| Kepastian ritme | mudah diprediksi dan diaudit | ritme mengikuti kejadian, bisa berloncatan |
| Cocok untuk | agregasi batch, laporan harian | data tiba tidak menentu, kebutuhan segar |
Pemicu event tidak menggantikan jadwal — keduanya berdampingan di platform data yang sama. Jadwal tetap memimpin untuk beban batch yang ritmenya stabil, sementara event mengambil alih bagian pipeline yang nilai utamanya adalah kesegaran.
Tiga Pola Pemicu #
Tiga mekanisme pemicu paling umum, dari yang paling sederhana ke yang paling lengkap:
- Sensor (polling) — orchestrator memeriksa sumber secara berkala: apakah ada berkas baru di object storage, apakah tabel sumber bertambah barisnya. Pola ini kita lihat langsung pada sensor Dagster di bab sebelumnya, dan Airflow menyediakan keluarga operator sensor yang serupa. Batas latensinya adalah interval polling — pemeriksaan tiap 30 detik berarti kejadian bisa menunggu hingga 30 detik.
- Message queue — pipeline menjadi consumer yang menunggu pesan dari broker seperti Kafka; setiap pesan (atau kumpulan kecil pesan) langsung memicu pemrosesan, dan offset mencatat posisi baca sehingga pesan tidak terlewat. Latensinya paling rendah dan skala paling besar, dengan harga berupa infrastruktur dan operasi broker.
- Webhook — sistem eksternal memanggil endpoint HTTP milik kita setiap kali kejadian terjadi, dan endpoint tersebut memicu run orchestrator. Pola ini menuntut autentikasi, validasi payload, dan pembatasan laju panggilan karena endpoint terbuka ke pihak luar.
Prefect menyediakan jalan pintas untuk pola ini lewat automation — aturan yang memicu deployment ketika event tertentu terjadi — sehingga webhook dan pesan dapat masuk tanpa menulis dispatcher sendiri. Detail broker pesan yang menjadi fondasi pola message queue dapat dibaca di dokumentasi Apache Kafka .
Simulasi Dispatcher Event #
Inti semua pola di atas adalah satu struktur: event masuk ke antrean, sebuah loop mengambil event, dan tabel routing memutuskan handler mana yang dijalankan. Simulasi berikut memperlihatkan struktur tersebut dengan Python murni — kode ini dijalankan nyata:
"""Simulasi dispatcher event sederhana — dijalankan nyata di bab ini."""
from dataclasses import dataclass
from queue import Empty, Queue
@dataclass
class Event:
jenis: str
payload: dict
def proses_pesanan(berkas: str) -> None:
print(f"[pipeline-pesanan] memproses {berkas}")
def proses_stok(berkas: str) -> None:
print(f"[pipeline-stok] memproses {berkas}")
HANDLER = {
"pesanan": proses_pesanan,
"stok": proses_stok,
}
def main() -> None:
antrean: Queue = Queue()
# simulasi dua event tiba nyaris bersamaan
antrean.put(Event("pesanan", {"berkas": "pesanan-2026-01-15.jsonl"}))
antrean.put(Event("stok", {"berkas": "stok-2026-01-15.csv"}))
while True:
try:
event = antrean.get_nowait()
except Empty:
break
handler = HANDLER.get(event.jenis)
if handler is None:
print(f"[dispatcher] tidak ada handler untuk {event.jenis}")
continue
handler(**event.payload)
antrean.task_done()
print("[dispatcher] antrean kosong:", antrean.empty())
if __name__ == "__main__":
main()Output yang Dihasilkan:
[pipeline-pesanan] memproses pesanan-2026-01-15.jsonl
[pipeline-stok] memproses stok-2026-01-15.csv
[dispatcher] antrean kosong: TrueMari kita telaah baris-baris kode di atas:
- Baris 7-10 (
Event): satu event hanya membawajenisdanpayload— struktur datar yang mudah diserialisasi ketika antreannya berpindah dari memori ke broker sungguhan. - Baris 21-24 (
HANDLER): tabel routing memisahkan dispatcher dari pipeline; menangani jenis event baru cukup menambah satu entri, tanpa menyentuh loop. - Baris 34-44 (loop utama): dispatcher mengambil event satu per satu sampai antrean kosong, memanggil handler yang cocok, lalu menandai pekerjaan selesai dengan
task_done()— pola konsumsi yang sama dengan consumer Kafka. - Baris 40-42 (handler kosong): event tanpa handler tidak menghentikan dispatcher, hanya dicatat — penting ketika produsen event berkembang lebih cepat daripada konsumen.
Dalam sistem produksi, Queue diganti topic Kafka, loop berjalan sebagai service yang selalu hidup, dan setiap handler adalah pipeline orchestrator — tetapi struktur keputusannya tetap sama.
Trade-off Event-Driven #
Pola event memberi latensi rendah dengan bayaran pada empat sisi:
- Pengiriman ulang — broker umumnya menjamin at-least-once: pesan yang sama bisa dikirim lebih dari sekali ketika jaringan bermasalah, sehingga setiap pipeline harus idempotent — konsep yang kita uji tuntas pada Chapter Backfill.
- Pengurutan — kejadian bisa tiba di luar urutan aslinya, terutama dengan banyak consumer; pipeline perlu menoleransi atau mengurutkan ulang berdasar waktu kejadian di payload.
- Backpressure — saat kejadian tiba lebih cepat daripada kecepatan pemrosesan, antrean menumpuk; kedalaman antrean menjadi metrik yang wajib dipantau.
- Observabilitas — satu pipeline terpecah menjadi banyak run kecil yang dipicu terpisah; ringkasan metrik run pada Chapter Monitoring Workflow menjadi satu-satunya cara melihat kesehatan keseluruhan.
Dengan jadwal, event, dan tiga orchestrator di tangan, pertanyaan penutup section ini tinggal satu: bagaimana memilih di antara semuanya? Kerangka keputusannya kita susun pada Chapter Memilih Workflow Orchestrator.