











{"author":"Faiq Najib Al-Aziz","body":"\nSistem GPS bisa terlihat sehat karena server menerima koneksi dan beberapa titik lokasi muncul di peta. Namun, satu bagian pipeline yang tertahan dapat membuat posisi yang ditampilkan sudah usang: listener masih menerima byte, worker tertinggal, antrean membesar, atau penulisan ke penyimpanan gagal berulang.\n\nKarena itu, reliability bukan sekadar menjaga proses tetap hidup. Kita perlu tahu data apa yang berhasil diterima, apa yang belum diproses, apa yang gagal, dan tindakan apa yang aman dilakukan ketika salah satu komponen tidak tersedia.\n\nSaya tulis ini sebagai kerangka berpikir untuk pipeline ingestion GPS. Contoh kode di sini ilustrasi, bukan implementasi lengkap, dan tidak menyatakan hasil produksi atau jaminan availability.\n\n## Petakan alur dan batas kegagalan\n\nPipeline sederhana dapat dipetakan seperti ini:\n\n```text\nTracker\n  -\u003e koneksi TCP\n  -\u003e framing dan validasi paket\n  -\u003e antrean kerja\n  -\u003e decode dan normalisasi\n  -\u003e penyimpanan atau layanan downstream\n  -\u003e pembaruan status yang dibaca operator\n```\n\nSetiap panah adalah batas yang perlu dipahami. Koneksi TCP dapat terputus. Frame dapat belum lengkap atau tidak valid. Worker dapat tertahan. Database dapat menolak koneksi atau menulis lebih lambat dari laju masuk. Consumer dashboard bisa terputus tanpa mengganggu ingestion, atau justru menghabiskan resource tanpa batas jika desainnya tidak membatasi klien.\n\nTanyakan pada setiap tahap:\n\n- Apakah data sudah diterima hanya di memori, atau sudah tersimpan secara durable?\n- Siapa yang mengetahui kegagalan?\n- Apakah pengirim dapat mencoba lagi?\n- Bagaimana kita mengenali data ganda?\n- Apa perilaku sistem ketika kapasitas downstream terlampaui?\n\nJawaban “sudah diterima” perlu spesifik. Byte yang dibaca dari socket belum tentu sudah diproses, dan pesan yang masuk ke channel di memori belum tentu bertahan jika proses berhenti.\n\n## Retry: ulangi hanya pekerjaan yang aman\n\nRetry berguna untuk kegagalan sementara, misalnya koneksi downstream yang sebentar tidak tersedia. Tetapi retry bukan obat untuk setiap error. Mengulang payload yang ditolak karena format tidak valid tidak akan membuatnya menjadi valid. Mengulang operasi yang sudah berhasil tetapi responsnya hilang dapat membuat efek ganda.\n\nSebelum retry, bedakan setidaknya:\n\n1. **Error sementara:** mungkin pulih setelah menunggu atau membangun ulang koneksi.\n2. **Error permanen untuk pesan itu:** perlu dicatat, diperbaiki, atau dikarantina. Retry tanpa perubahan hanya mengulang kegagalan.\n3. **Error yang hasilnya tidak diketahui:** downstream mungkin sudah melakukan pekerjaan tetapi balasan tidak sampai.\n\nUntuk kategori ketiga, tentukan idempotensi. Jika protokol menyediakan nomor urut atau identitas pesan, gunakan informasi tersebut sesuai semantiknya. Jika tidak ada identitas stabil, jangan mengklaim deduplikasi sempurna; pilih dan dokumentasikan kompromi yang sesuai dengan dampak duplikasi.\n\nHindari retry rapat tanpa batas. Gunakan batas percobaan atau waktu, jeda yang meningkat, dan variasi jeda agar banyak worker tidak mencoba kembali serempak. Setelah batas tercapai, kegagalan perlu terlihat dan mengikuti kebijakan, misalnya masuk antrean durable untuk ditinjau, menolak koneksi agar sumber mencoba ulang, atau mengirim pesan ke jalur karantina. Pilihan bergantung pada kemampuan perangkat dan risiko kehilangan atau duplikasi data.\n\nPseudocode berikut menunjukkan urutannya, bukan API siap pakai:\n\n```text\nattempt = 0\nwhile within retry budget:\n    result = write(event)\n    if success:\n        acknowledge only when the delivery contract allows it\n        stop\n    if error is permanent:\n        record and quarantine or reject\n        stop\n    wait with bounded exponential backoff and jitter\nif still failing:\n    emit a visible failure and apply the documented recovery policy\n```\n\nRetry perlu punya batas, error perlu bisa diklasifikasikan, dan kontrak acknowledgement tidak boleh membuat pengirim mengira data aman padahal hanya tersimpan di memori.\n\n## Backpressure: kapasitas harus punya batas\n\nAntrean membantu menyerap lonjakan singkat, tetapi antrean tanpa batas hanya menunda kegagalan sambil memakai memori lebih banyak. Antrean berbatas membuat sistem harus mengambil keputusan saat consumer tidak mampu mengejar producer.\n\nContoh berikut menunjukkan channel terbatas di Go:\n\n```go\njobs := make(chan Packet, 256)\n\nselect {\ncase jobs \u003c- packet:\n    // Paket diterima ke antrean dalam memori.\ndefault:\n    // Kapasitas penuh: jalankan kebijakan overload yang sudah ditentukan.\n    return ErrOverloaded\n}\n```\n\n`Packet` dan `ErrOverloaded` adalah placeholder konseptual, bukan tipe dari aplikasi ini. Channel tersebut berada di memori: jika proses berhenti sebelum worker menyimpan paket, isi antrean dapat hilang.\n\nSaat penuh, beberapa pilihan yang mungkin adalah:\n\n- **Menahan pembacaan sementara.** Ini meneruskan tekanan ke koneksi, tetapi hanya berguna jika perangkat dan protokol menangani jeda dengan baik.\n- **Menolak atau memutus koneksi.** Sumber mungkin akan mengirim ulang, tetapi perilaku ini perlu dibuktikan untuk perangkat yang digunakan.\n- **Menyimpan ke antrean durable.** Ini menambah kebutuhan operasi, retensi, deduplikasi, dan pemulihan.\n- **Menolak atau melepas data tertentu.** Hanya layak bila kebijakan bisnis mengizinkan kehilangan jenis data tersebut dan kehilangan itu terlihat.\n\nTidak ada kebijakan universal. Pilih berdasarkan nilai data, kemampuan retry dari perangkat, dan apa yang boleh terjadi ketika kapasitas habis. Apa pun pilihannya, jangan membiarkan overload berubah menjadi kehilangan diam-diam.\n\n## Observability yang menjawab pertanyaan operasional\n\nLog “error” saja tidak menunjukkan apakah data terlambat atau apakah tim perlu bertindak. Mulailah dengan sinyal yang menghubungkan komponen dan dampak:\n\n| Sinyal | Pertanyaan yang dijawab |\n|---|---|\n| Koneksi aktif, ditolak, dan putus | Apakah sumber dapat terhubung dan mempertahankan sesi? |\n| Paket diterima, tidak valid, dan gagal decode | Apakah format atau kualitas data berubah? |\n| Kedalaman antrean dan usia item tertua | Apakah consumer mengejar laju masuk? |\n| Jumlah retry dan hasil akhirnya | Apakah gangguan sementara pulih, atau kegagalan menumpuk? |\n| Latensi pemrosesan dan penulisan | Tahap mana yang mulai tertahan? |\n| Waktu posisi direkam dibanding diterima | Seberapa segar informasi yang dilihat pengguna? |\n\nDefinisikan nama, satuan, sumber, dan rentang pengukuran. Untuk menghitung freshness, bandingkan waktu posisi yang disediakan sumber dengan waktu penerimaan, sambil menangani perbedaan jam dan timestamp yang hilang. Jangan menyimpulkan perangkat offline hanya dari satu titik yang terlambat tanpa memeriksa koneksi dan aturan pelaporan.\n\nGunakan identitas perangkat sebagai label dengan hati-hati. Label ber-cardinality tinggi pada sistem metrik dapat menyulitkan penyimpanan dan query. Detail per perangkat dapat lebih sesuai di log terstruktur atau sistem investigasi, dengan kebijakan akses dan retensi yang sesuai.\n\n## Ilustrasi kegagalan sintetis\n\nBayangkan sebuah consumer penyimpanan melambat sementara listener masih menerima paket. Antrean berbatas mulai terisi. Dengan hanya metrik jumlah koneksi, sistem mungkin tampak sehat. Dengan metrik usia item tertua dan latensi penulisan, operator dapat melihat bahwa data tertahan sebelum sampai ke penyimpanan.\n\nTim kemudian menjalankan kebijakan overload yang telah dipilih, misalnya menahan pembacaan atau mengirim data ke antrean durable, dan mencatat apakah paket dapat diproses setelah downstream pulih. Ini skenario sintetis untuk menjelaskan cara berpikir.\n\n## Uji perilaku saat sistem tertekan\n\nJangan hanya menguji jalur sukses. Buat skenario uji yang meliputi:\n\n- koneksi putus saat frame belum lengkap;\n- paket malformed atau duplikat;\n- database lambat atau tidak tersedia;\n- antrean mencapai batas;\n- worker berhenti dan dimulai kembali;\n- proses restart saat ada data yang belum durable;\n- sumber mengirim ulang setelah koneksi terputus.\n\nUntuk tiap skenario, tentukan hasil yang diharapkan: data ditolak, ditunda, dicoba ulang, dikarantina, atau diproses satu kali bila kontrak sistem mendukungnya. Catat juga bagaimana operator mengetahui keadaan tersebut. Gunakan perangkat simulasi atau fixture yang tidak mengandung data rahasia.\n\n## Checklist singkat\n\n- Batas antara diterima, diantrekan, diproses, dan disimpan dijelaskan.\n- Retry hanya digunakan untuk error yang sesuai dan memiliki batas.\n- Operasi yang diulang memiliki kebijakan idempotensi atau duplikasi yang eksplisit.\n- Semua antrean memiliki batas serta perilaku overload yang disepakati.\n- Data di memori tidak disebut durable.\n- Metrik menunjukkan usia data dan tahap pipeline yang tertahan.\n- Jalur error terlihat dan memiliki pemilik tindak lanjut.\n- Kegagalan penting diuji dengan skenario yang dapat diulang.\n\nKalau tim kamu sedang menilai integrasi atau pilot sistem armada, [hubungi Akordium Lab untuk mendiskusikan workflow dan batas implementasinya](https://akordium.id/contact).\n\nSekian. Salam.\n","body_clean":"Sistem GPS bisa terlihat sehat karena server menerima koneksi dan beberapa titik lokasi muncul di peta. Namun, satu bagian pipeline yang tertahan dapat membuat posisi yang ditampilkan sudah usang: listener masih menerima byte, worker tertinggal, antrean membesar, atau penulisan ke penyimpanan gagal berulang.\nKarena itu, reliability bukan sekadar menjaga proses tetap hidup. Kita perlu tahu data apa yang berhasil diterima, apa yang belum diproses, apa yang gagal, dan tindakan apa yang aman dilakukan ketika salah satu komponen tidak tersedia.\nSaya tulis ini sebagai kerangka berpikir untuk pipeline ingestion GPS. Contoh kode di sini ilustrasi, bukan implementasi lengkap, dan tidak menyatakan hasil produksi atau jaminan availability.\nPetakan alur dan batas kegagalan #Pipeline sederhana dapat dipetakan seperti ini:\nTracker -\u0026gt; koneksi TCP -\u0026gt; framing dan validasi paket -\u0026gt; antrean kerja -\u0026gt; decode dan normalisasi -\u0026gt; penyimpanan atau layanan downstream -\u0026gt; pembaruan status yang dibaca operator Setiap panah adalah batas yang perlu dipahami. Koneksi TCP dapat terputus. Frame dapat belum lengkap atau tidak valid. Worker dapat tertahan. Database dapat menolak koneksi atau menulis lebih lambat dari laju masuk. Consumer dashboard bisa terputus tanpa mengganggu ingestion, atau justru menghabiskan resource tanpa batas jika desainnya tidak membatasi klien.\nTanyakan pada setiap tahap:\nApakah data sudah diterima hanya di memori, atau sudah tersimpan secara durable? Siapa yang mengetahui kegagalan? Apakah pengirim dapat mencoba lagi? Bagaimana kita mengenali data ganda? Apa perilaku sistem ketika kapasitas downstream terlampaui? Jawaban “sudah diterima” perlu spesifik. Byte yang dibaca dari socket belum tentu sudah diproses, dan pesan yang masuk ke channel di memori belum tentu bertahan jika proses berhenti.\nRetry: ulangi hanya pekerjaan yang aman #Retry berguna untuk kegagalan sementara, misalnya koneksi downstream yang sebentar tidak tersedia. Tetapi retry bukan obat untuk setiap error. Mengulang payload yang ditolak karena format tidak valid tidak akan membuatnya menjadi valid. Mengulang operasi yang sudah berhasil tetapi responsnya hilang dapat membuat efek ganda.\nSebelum retry, bedakan setidaknya:\nError sementara: mungkin pulih setelah menunggu atau membangun ulang koneksi. Error permanen untuk pesan itu: perlu dicatat, diperbaiki, atau dikarantina. Retry tanpa perubahan hanya mengulang kegagalan. Error yang hasilnya tidak diketahui: downstream mungkin sudah melakukan pekerjaan tetapi balasan tidak sampai. Untuk kategori ketiga, tentukan idempotensi. Jika protokol menyediakan nomor urut atau identitas pesan, gunakan informasi tersebut sesuai semantiknya. Jika tidak ada identitas stabil, jangan mengklaim deduplikasi sempurna; pilih dan dokumentasikan kompromi yang sesuai dengan dampak duplikasi.\nHindari retry rapat tanpa batas. Gunakan batas percobaan atau waktu, jeda yang meningkat, dan variasi jeda agar banyak worker tidak mencoba kembali serempak. Setelah batas tercapai, kegagalan perlu terlihat dan mengikuti kebijakan, misalnya masuk antrean durable untuk ditinjau, menolak koneksi agar sumber mencoba ulang, atau mengirim pesan ke jalur karantina. Pilihan bergantung pada kemampuan perangkat dan risiko kehilangan atau duplikasi data.\nPseudocode berikut menunjukkan urutannya, bukan API siap pakai:\nattempt = 0 while within retry budget: result = write(event) if success: acknowledge only when the delivery contract allows it stop if error is permanent: record and quarantine or reject stop wait with bounded exponential backoff and jitter if still failing: emit a visible failure and apply the documented recovery policy Retry perlu punya batas, error perlu bisa diklasifikasikan, dan kontrak acknowledgement tidak boleh membuat pengirim mengira data aman padahal hanya tersimpan di memori.\nBackpressure: kapasitas harus punya batas #Antrean membantu menyerap lonjakan singkat, tetapi antrean tanpa batas hanya menunda kegagalan sambil memakai memori lebih banyak. Antrean berbatas membuat sistem harus mengambil keputusan saat consumer tidak mampu mengejar producer.\nContoh berikut menunjukkan channel terbatas di Go:\njobs := make(chan Packet, 256) select { case jobs \u0026lt;- packet: // Paket diterima ke antrean dalam memori. default: // Kapasitas penuh: jalankan kebijakan overload yang sudah ditentukan. return ErrOverloaded } Packet dan ErrOverloaded adalah placeholder konseptual, bukan tipe dari aplikasi ini. Channel tersebut berada di memori: jika proses berhenti sebelum worker menyimpan paket, isi antrean dapat hilang.\nSaat penuh, beberapa pilihan yang mungkin adalah:\nMenahan pembacaan sementara. Ini meneruskan tekanan ke koneksi, tetapi hanya berguna jika perangkat dan protokol menangani jeda dengan baik. Menolak atau memutus koneksi. Sumber mungkin akan mengirim ulang, tetapi perilaku ini perlu dibuktikan untuk perangkat yang digunakan. Menyimpan ke antrean durable. Ini menambah kebutuhan operasi, retensi, deduplikasi, dan pemulihan. Menolak atau melepas data tertentu. Hanya layak bila kebijakan bisnis mengizinkan kehilangan jenis data tersebut dan kehilangan itu terlihat. Tidak ada kebijakan universal. Pilih berdasarkan nilai data, kemampuan retry dari perangkat, dan apa yang boleh terjadi ketika kapasitas habis. Apa pun pilihannya, jangan membiarkan overload berubah menjadi kehilangan diam-diam.\nObservability yang menjawab pertanyaan operasional #Log “error” saja tidak menunjukkan apakah data terlambat atau apakah tim perlu bertindak. Mulailah dengan sinyal yang menghubungkan komponen dan dampak:\nSinyal Pertanyaan yang dijawab Koneksi aktif, ditolak, dan putus Apakah sumber dapat terhubung dan mempertahankan sesi? Paket diterima, tidak valid, dan gagal decode Apakah format atau kualitas data berubah? Kedalaman antrean dan usia item tertua Apakah consumer mengejar laju masuk? Jumlah retry dan hasil akhirnya Apakah gangguan sementara pulih, atau kegagalan menumpuk? Latensi pemrosesan dan penulisan Tahap mana yang mulai tertahan? Waktu posisi direkam dibanding diterima Seberapa segar informasi yang dilihat pengguna? Definisikan nama, satuan, sumber, dan rentang pengukuran. Untuk menghitung freshness, bandingkan waktu posisi yang disediakan sumber dengan waktu penerimaan, sambil menangani perbedaan jam dan timestamp yang hilang. Jangan menyimpulkan perangkat offline hanya dari satu titik yang terlambat tanpa memeriksa koneksi dan aturan pelaporan.\nGunakan identitas perangkat sebagai label dengan hati-hati. Label ber-cardinality tinggi pada sistem metrik dapat menyulitkan penyimpanan dan query. Detail per perangkat dapat lebih sesuai di log terstruktur atau sistem investigasi, dengan kebijakan akses dan retensi yang sesuai.\nIlustrasi kegagalan sintetis #Bayangkan sebuah consumer penyimpanan melambat sementara listener masih menerima paket. Antrean berbatas mulai terisi. Dengan hanya metrik jumlah koneksi, sistem mungkin tampak sehat. Dengan metrik usia item tertua dan latensi penulisan, operator dapat melihat bahwa data tertahan sebelum sampai ke penyimpanan.\nTim kemudian menjalankan kebijakan overload yang telah dipilih, misalnya menahan pembacaan atau mengirim data ke antrean durable, dan mencatat apakah paket dapat diproses setelah downstream pulih. Ini skenario sintetis untuk menjelaskan cara berpikir.\nUji perilaku saat sistem tertekan #Jangan hanya menguji jalur sukses. Buat skenario uji yang meliputi:\nkoneksi putus saat frame belum lengkap; paket malformed atau duplikat; database lambat atau tidak tersedia; antrean mencapai batas; worker berhenti dan dimulai kembali; proses restart saat ada data yang belum durable; sumber mengirim ulang setelah koneksi terputus. Untuk tiap skenario, tentukan hasil yang diharapkan: data ditolak, ditunda, dicoba ulang, dikarantina, atau diproses satu kali bila kontrak sistem mendukungnya. Catat juga bagaimana operator mengetahui keadaan tersebut. Gunakan perangkat simulasi atau fixture yang tidak mengandung data rahasia.\nChecklist singkat # Batas antara diterima, diantrekan, diproses, dan disimpan dijelaskan. Retry hanya digunakan untuk error yang sesuai dan memiliki batas. Operasi yang diulang memiliki kebijakan idempotensi atau duplikasi yang eksplisit. Semua antrean memiliki batas serta perilaku overload yang disepakati. Data di memori tidak disebut durable. Metrik menunjukkan usia data dan tahap pipeline yang tertahan. Jalur error terlihat dan memiliki pemilik tindak lanjut. Kegagalan penting diuji dengan skenario yang dapat diulang. Kalau tim kamu sedang menilai integrasi atau pilot sistem armada, hubungi Akordium Lab untuk mendiskusikan workflow dan batas implementasinya.\nSekian. Salam.\n","canonical":"https://najib.id/writing/2026/realtime-pipeline-reliability/","description":"Cara memikirkan kegagalan, retry, backpressure, dan observability pada pipeline GPS real-time tanpa menganggap data selalu lengkap atau tersedia.","language":"id","lastmod":"2026-11-11T23:31:00Z","publishedAt":"2026-10-24T00:00:00Z","readingTime":6,"section":"writing","series":"","tags":["golang","gps","reliability","streaming"],"title":"Reliability Pipeline GPS Real-Time: Retry, Backpressure, dan Observability","type":"writing","url":"https://najib.id/writing/2026/realtime-pipeline-reliability/","wordCount":1173}
