Kondisi ras data jaringan dari neraka
Saya sedang menulis klien jaringan / server (Windows XP / C #) untuk bekerja dengan aplikasi serupa pada workstation yang sangat lama (Encore 32/77) yang ditulis oleh pengembang lain.
Apa yang dilakukan aplikasi pada dasarnya adalah berbagi / memanipulasi data tertentu pada host untuk mengontrol proses host yang menjalankan sistem dengan UI layar sentuh multi-monitor mewah berbasis PC kami.
Itu melakukan ini dengan struktur 3 lapis. Proses komunikasi membaca / menulis data ke / dari host, melakukan semua konversi format yang diperlukan (endianness, format floating point, dll) dan menulis / membaca nilai-nilai ke / dari database. Basis data bertindak sebagai perantara data antara comms dan UI layar sentuh. Aplikasi UI layar sentuh menghasilkan antarmuka layar sentuh berdasarkan berapa banyak monitor yang terpasang pada PC (secara otomatis mendeteksi ini).
Dalam jangka waktu yang diberikan paket nilai antara host dan pc kami hanya bisa mengirim 128 nilai maks melalui kabel pada suatu waktu dengan latensi maksimum ~ 110ms per round trip (UDP digunakan dengan koneksi ethernet x-over langsung antara komputer). Jadi, jumlah variabel yang diizinkan berdasarkan jumlah variabel layar sentuh yang terpasang berada di bawah kendali ketat. Juga, tuan rumah (walaupun memiliki arsitektur multi-prosesor yang cukup kompleks dengan bus memori bersama yang digunakan untuk komputasi waktu nyata) memiliki sekitar 1/100 kekuatan pemrosesan ponsel saya sehingga ditugaskan untuk melakukan pemrosesan sesedikit mungkin dan servernya / klien harus ditulis dalam pertemuan untuk memastikan hal ini (tuan rumah menjalankan simulasi waktu nyata yang tidak dapat dipengaruhi oleh program kami).
Masalahnya adalah. Beberapa nilai, ketika diubah pada layar sentuh tidak akan hanya mengambil nilai yang baru dimasukkan tetapi akan siklus secara acak antara nilai itu dan nilai sebelumnya. Itu dan hanya pada beberapa nilai tertentu pada beberapa halaman tertentu dengan kombinasi halaman tertentu yang pernah menunjukkan gejala. Kami hampir melewatkan masalah sepenuhnya sampai kami mulai menjalankannya melalui proses penerimaan pelanggan awal
Untuk menjelaskan masalah ini, saya memilih salah satu nilai berosilasi:
- Saya memeriksa aplikasi Touchscreen, itu berosilasi
- Saya memeriksa database, berosilasi
- Saya memeriksa aplikasi comms, berosilasi
Kemudian saya pecah wireshark dan mulai secara manual decoding paket menangkap. Hasil:
- Tidak terombang-ambing tetapi paket tidak terlihat benar, ada terlalu banyak data.
Saya melangkah melalui setiap detail kode komunikasi seratus kali tanpa menemukan cacat / kesalahan.
Akhirnya saya mulai mengirim email ke dev lain yang bertanya secara detail bagaimana akhirnya dia bekerja untuk melihat apakah ada sesuatu yang saya lewatkan. Lalu saya menemukannya.
Rupanya, ketika dia mengirim data dia tidak menyiram array data sebelum pengiriman jadi, pada dasarnya, dia hanya menimpa buffer terakhir yang digunakan dengan nilai-nilai baru menimpa yang lama, tetapi nilai-nilai lama yang tidak ditimpa masih dikirim.
Jadi, jika nilai berada di posisi 80 dari array data dan daftar nilai yang diminta berubah menjadi kurang dari 80 tetapi nilai yang sama terkandung dalam daftar baru, maka kedua nilai akan ada di buffer data untuk buffer spesifik di setiap diberikan waktu.
Nilai yang dibaca dari database tergantung pada irisan waktu ketika UI meminta nilai.
Cara mengatasinya sangat sederhana. Baca dalam jumlah item yang masuk pada buffer data (Itu sebenarnya terkandung sebagai bagian dari protokol paket) dan jangan membaca buffer di luar jumlah item.
Pelajaran yang dipelajari:
Jangan anggap daya komputasi modern begitu saja. Ada saat ketika komputer tidak mendukung ethernet dan ketika membilas array dapat dianggap mahal. Jika Anda benar-benar ingin melihat seberapa jauh kami datang, bayangkan sebuah sistem yang hampir tidak memiliki bentuk alokasi memori dinamis. IE, proses eksekutif harus pra-mengalokasikan semua memori untuk semua program agar dan tidak ada program yang dapat tumbuh melampaui batas itu. Yaitu, mengalokasikan lebih banyak memori ke program tanpa mengkompilasi ulang seluruh sistem dapat menyebabkan crash besar. Saya ingin tahu apakah orang akan berbicara tentang hari-hari pengumpulan sampah di hari yang sama suatu hari nanti.
Saat melakukan jaringan dengan protokol khusus (atau menangani representasi data biner secara umum), pastikan Anda membaca spesifikasi hingga Anda memahami setiap fungsi dari setiap nilai yang dikirim melintasi pipa. Maksudku, baca sampai matamu sakit. Orang yang menangani data dengan memanipulasi bit atau byte individu memiliki cara yang sangat cerdas dan efisien dalam melakukan sesuatu. Kehilangan detail terkecil dapat merusak sistem.
Waktu keseluruhan untuk memperbaikinya adalah 2-3 hari dengan sebagian besar waktu itu dihabiskan untuk mengerjakan hal-hal lain ketika saya merasa frustrasi dengan ini.
SideNote: Komputer host yang dimaksud tidak mendukung ethernet secara default. Kartu untuk dikendarai dibuat khusus dan dipasang kembali dan tumpukan protokol hampir tidak ada. Pengembang tempat saya bekerja adalah seorang programmer yang hebat, dia tidak hanya mengimplementasikan versi UDP yang dipreteli dan tumpukan ethernet palsu mimimal (prosesor tidak cukup kuat untuk menangani tumpukan ethernet penuh) pada sistem untuk proyek ini. tapi dia melakukannya dalam waktu kurang dari seminggu. Dia juga menjadi salah satu pemimpin tim proyek asli yang telah merancang dan memprogram OS di tempat pertama. Katakan saja, apa saja yang pernah dia bagikan tentang komputer / pemrograman / arsitektur tidak peduli berapa lama atau berapa banyak saya sudah baru, saya akan mendengarkan setiap kata.