Semua orang menginginkan pembaruan real-time sampai mereka menyadari bahwa "cepat" dan "benar" tidaklah sama. Dalam sistem terdistribusi, peristiwa dapat bergerak secepat cahaya namun tetap sampai dalam urutan yang salah. WebSocket terputus dan menyambung kembali. Broker pesan mengirim ulang paket. Pekerja latar belakang berlomba melawan pembatalan timeout. Hasilnya? Klien mungkin melihat peristiwa 42, lalu peristiwa 40, kemudian sebuah snapshot yang menyatakan sistem sudah berada di peristiwa 45. Jika Anda sedang membangun alur kerja agen yang berjalan lama (long-running agent workflows), kekacauan tersebut bukanlah sebuah edge case. Itu adalah kondisi dasar. Perbaiki urutan peristiwa Anda sebelum Anda mengkhawatirkan memangkas milidetik pada pengiriman.
Realitas "Real-Time" yang Berantakan
Real-time adalah properti transportasi. Ini menjelaskan seberapa cepat sebuah paket bergerak melalui kabel, bukan apakah cerita yang disampaikan masuk akal. Tugas-tugas yang berjalan lama memperkuat setiap inkonsistensi karena mereka membentang melintasi waktu. Pekerjaan pelatihan model, alur persetujuan multi-langkah, atau pipeline rendering video mungkin memancarkan puluhan peristiwa selama beberapa menit atau jam. Selama jendela waktu tersebut, apa pun bisa salah.
Broker mungkin mencoba lagi sebuah pesan karena konfirmasi (acknowledgement) hilang. Load balancer mungkin mengarahkan dua peristiwa melalui jalur jaringan yang berbeda, sehingga peristiwa yang lebih baru tiba lebih dulu. Sebuah proses pekerja mungkin mati setelah menulis ke database tetapi sebelum mempublikasikan peristiwa keberhasilan, hanya untuk kemudian pekerja kedua mengambil tugas tersebut dan memancarkan progresnya sendiri. Jika frontend Anda berasumsi bahwa pesan terbaru adalah pesan yang paling benar, ia akan menampilkan status yang tidak pernah ada. Pengguna akan melihat lencana "selesai" berkedip kembali ke "sedang diproses," atau lebih buruk lagi, tugas yang dibatalkan tiba-tiba muncul kembali. Kecepatan tanpa pengurutan hanyalah kebingungan dengan frame rate yang lebih tinggi.
Nomor Urutan Adalah Jam yang Sebenarnya
Solusinya adalah nomor urutan monoton yang ketat yang dihasilkan oleh produsen. Setiap operasi yang mengubah status mendapatkan nomor yang bertambah tepat satu, tanpa celah dan tanpa rollback. Nomor tersebut harus disimpan dalam transaksi yang sama dengan peristiwa itu sendiri. Jika baris database diperbarui tetapi commit urutan gagal, Anda melakukan rollback pada keduanya. Ini menjaga lini masa logis tetap atomik dengan perubahan status.
ID peristiwa masih berguna, tetapi mereka menyelesaikan masalah yang berbeda. Sebuah ID peristiwa mengidentifikasi payload tertentu sehingga Anda dapat melakukan deduplikasi saat broker mengirimkan pesan yang sama dua kali. Di sisi lain, nomor urutan memberi tahu Anda di mana payload tersebut berada dalam rantai kausal. Ia menunjukkan celah. Ia menunjukkan pengurutan. Timestamp tidak melakukan keduanya. Jam bisa bergeser (drift), NTP melompat mundur, dan mesin virtual bisa berhenti sejenak (pause). Gunakan timestamp hanya untuk tujuan tampilan, seperti "Dimulai 3 menit yang lalu," dan jangan pernah sebagai kunci pengurutan untuk logika bisnis.
Bagaimana Klien Harus Menangani Stream
Setelah produsen menjamin urutan monoton, konsumen mendapatkan aturan yang sederhana dan kaku. Jika nomor urutan yang masuk kurang dari atau sama dengan nomor terakhir yang diterapkan, buanglah. Itu bisa jadi duplikat atau pendatang terlambat yang sudah usang. Jika urutannya tepat satu lebih besar dari nomor terakhir yang diterapkan, terapkan segera. Itulah happy path. Jika urutannya melompat maju, misalnya Anda mengharapkan 12 tetapi menerima 15, ada sesuatu yang hilang. Simpan (buffer) peristiwa baru tersebut dan minta server untuk memutar ulang (replay) mulai dari urutan berikutnya yang diharapkan. Jangan menebak. Jangan melompat maju dengan berharap celah tersebut tidak masalah.
Status terminal harus diperlakukan sebagai tidak dapat dibatalkan (irrevocable). Begitu sebuah tugas ditandai selesai, gagal, atau dibatalkan, klien harus menolak setiap perubahan status berikutnya untuk operasi tersebut. Ini terdengar jelas sampai Anda berurusan dengan
