17 poin oleh GN⁺ 2024-08-04 | 3 komentar | Bagikan ke WhatsApp

"Tabel merchants2? Ya, kami membuat merchants2 karena kolom di merchants tidak cukup."

  • Saat pertama kali mulai belajar pemrograman, saya tidak tahu bahwa orang bisa menghasilkan uang dari pemrograman
  • Di pekerjaan software pertama saya, saya belajar banyak hal, dan codebase di sana adalah yang terburuk sekaligus yang terbaik

Database hidup selamanya

  • Dalam sistem legacy, database berperan lebih dari sekadar penyimpanan data. Ia menetapkan batasan untuk seluruh sistem dan menjadi titik temu semua kode
  • SQL Server memiliki batas jumlah kolom dalam tabel. Saat itu batasnya 1024, sekarang 4096. Karena kolom pada tabel Merchants tidak cukup, mereka membuat tabel Merchants2 (dengan lebih dari 500 kolom)
  • Merchants dan Merchants2 adalah inti sistem. Semua terhubung ke Merchants. Ada tabel lain yang lebih ternormalisasi, tetapi semuanya memiliki relasi foreign key dengan Merchants

SequenceKey

  • SequenceKey adalah tabel sederhana yang hanya memiliki satu kolom dan satu nilai
  • Tabel ini digunakan untuk pembuatan ID. Kemungkinan dibuat karena SQL Server saat itu tidak mendukung auto-increment ID
  • Di setiap stored procedure, sistem mengambil key dari SequenceKey lalu menaikkannya, dan menggunakannya sebagai ID di beberapa tabel. Ini berfungsi sebagai implicit join

Calendar

  • Calendar adalah tabel kalender yang diisi secara manual. Jika Calendar kedaluwarsa, pengguna tidak bisa login ke sistem
  • Hal ini pernah terjadi beberapa tahun lalu, lalu seorang intern menambahkan data untuk 5 tahun lagi. Tidak ada yang tahu sistem mana yang menggunakannya

Employees

  • Setiap pagi pukul 7:15, tabel employees dihapus lalu diisi ulang dari CSV yang diterima dari ADP
  • Selama proses ini, pengguna tidak bisa login ke sistem. Kadang-kadang proses ini juga gagal
  • Karena data harus direplikasi ke kantor pusat, data itu dikirim lewat email ke satu orang yang setiap hari menekan tombol untuk menyalinnya

Database pengganti

  • Mungkin terdengar seperti database ini seharusnya bisa dibersihkan. Perusahaan juga berpikir begitu
  • Ada salinan database ini, tetapi datanya terlambat sekitar 10 menit. Sinkronisasi hanya berjalan satu arah
  • Database ini sudah ternormalisasi, jadi untuk mencari nomor telepon di merchants dibutuhkan 7 join

Kinerja penjualan

  • Semua sales memiliki kuota bulanan yang disebut "win"
  • Tabel yang mengelolanya sangat rumit. Sebuah job harian berjalan untuk menemukan baris yang ditambahkan/diubah lalu menyinkronkannya dengan sistem kantor pusat
  • Masalah muncul ketika seorang sales meminta agar sebuah record diubah secara manual
  • Sales tersebut sudah mencapai target win dan kemudian mendapatkan penjualan besar lagi di bulan yang sama, tetapi ingin memindahkannya ke bulan berikutnya
  • Seorang intern menangani pekerjaan ini, lalu kabarnya menyebar dan selama 3 tahun jumlah permintaannya meningkat secara eksponensial
  • Pada satu titik, ada 3 intern yang pekerjaannya hanya menulis statement SQL. Membuat aplikasi untuk ini dianggap terlalu sulit

Codebase

  • Codebase pertama yang saya kenal ada di Team Foundation Server, sebuah sistem version control terpusat
  • Codebase utama yang saya kerjakan terdiri dari separuh VB dan separuh C#. Ia berjalan di IIS dan menggunakan session state di mana-mana
  • Artinya, jika Anda mengakses sebuah halaman lewat Path A atau Path B, Anda bisa melihat hal yang sangat berbeda di halaman yang sama
  • Semua framework JavaScript yang pernah ada saat itu sudah di-check in ke repo ini, biasanya disertai modifikasi kustom yang menurut penulisnya diperlukan. Yang paling menonjol adalah knockout, backbone, marionette, serta jquery dan plugin jquery
  • Selain codebase ini, ada juga sekitar 12 layanan SOAP dan beberapa aplikasi Windows native

Hard drive Gilfoyle

  • Gilfoyle dikenal sebagai programmer yang luar biasa cepat. Saya tidak pernah bertemu dengannya, tetapi saya mengenalnya lewat kodenya dan kode yang tertinggal di hard drive-nya
  • Munch menyimpan hard drive Gilfoyle di atas mejanya dalam konfigurasi RAID, meskipun Gilfoyle sudah meninggalkan perusahaan bertahun-tahun sebelumnya
  • Alasannya, Gilfoyle terkenal karena tidak check in kode dan justru membuat aplikasi Windows sekali pakai yang acak untuk satu pengguna tertentu
  • Tidak jarang ada pengguna datang membawa bug report untuk aplikasi yang hanya ada di hard drive Gilfoyle

Bug pengiriman

  • Sebagian besar pekerjaan saya adalah melacak bug yang tidak ingin dialokasikan tim ke siapa pun
  • Ada bug yang sangat menjengkelkan dan muncul setiap beberapa bulan: sebuah pesanan tersangkut di antrean pengiriman setelah dikirim, dan terlihat seolah belum dikirim padahal sebenarnya sudah
  • Untuk memperbaikinya, kami mencoba berbagai solusi seperti script SQL dan aplikasi Windows. Saya disarankan agar tidak menelusuri akar masalahnya, tetapi saya tidak tahan
  • Dalam prosesnya saya belajar cara berpikir Gilfoyle. Aplikasi pengiriman mengambil seluruh database, lalu memfilter berdasarkan tanggal dan menyimpan semua pesanan sejak tanggal mulai aplikasi itu
  • Aplikasi itu bergantung pada layanan SOAP, tetapi bukan untuk melakukan hal-hal ala service; ia hanyalah fungsi murni. Semua efek samping disebabkan oleh client
  • Di client itu, saya menemukan hierarki kelas raksasa: 120 kelas dengan beragam method, dan pewarisan sampai 10 level
  • Satu-satunya masalah adalah semua method itu kosong
  • Semua ini dibuat untuk membangun struktur yang bisa menggunakan reflection. Reflection tersebut membuat string yang dipisahkan dengan pipe (strukturnya berbasis database tetapi sepenuhnya statis) lalu mengirimkannya melalui socket
  • Pada akhirnya, data itu dikirim ke Kewill, layanan yang berkomunikasi dengan perusahaan pengangkutan. Bug itu terjadi karena Kewill memakai ulang angka 9 digit setiap bulan, dan seseorang menonaktifkan cron job yang menghapus pesanan lama

Kekacauan yang indah

  • Masih banyak yang bisa diceritakan tentang codebase ini: tim senior developer yang menghabiskan 5 tahun menulis ulang semuanya tanpa pernah merilis kode, atau konsultan Red Hat yang membangun satu database untuk mengendalikan semuanya
  • Codebase ini punya banyak sudut yang gila, dan banyak alasan mengapa seharusnya ada tim khusus yang memulai ulang satu fitur dari nol
  • Namun cerita yang paling penting adalah ketika Justin memperbaiki halaman Merchants Search. Halaman ini adalah pintu masuk ke seluruh aplikasi
  • Semua customer service rep menelepon merchant, lalu mengetik ID atau nama untuk mencari informasi. Setelah itu mereka masuk ke halaman besar yang memuat semua informasi
  • Halaman ini padat informasi dengan cara yang terbaik: berisi semua hal yang diperlukan dan semua tautan yang mungkin ingin dikunjungi. Namun, halamannya sangat lambat
  • Justin adalah satu-satunya senior developer di grup saya. Ia cerdas, sarkastik, dan tidak terlalu peduli pada bisnis
  • Ia mengatakan apa adanya, tidak menahan diri, dan selalu bisa menyelesaikan masalah sendirian lebih cepat daripada tim di sekitarnya
  • Suatu hari Justin muak mendengar betapa lambatnya halaman pencarian merchant itu, lalu ia pergi dan memperbaikinya
  • Setiap kotak di layar dijadikan endpoint tersendiri. Saat load, semua yang ada di atas fold mulai di-fetch, dan setelah satu selesai dimuat, request lain mulai masuk
  • Waktu muat halaman turun dari hitungan menit menjadi kurang dari satu detik

Dua cara melakukan decoupling

  • Justin bisa melakukan ini karena codebase ini tidak punya master plan
  • Tidak ada cetak biru kasar yang harus diikuti sistem, tidak ada format API yang diharapkan, tidak ada design system terdokumentasi, dan tidak ada dewan peninjau arsitektur yang menjamin konsistensi
  • Aplikasi ini benar-benar berantakan. Tidak ada yang bisa memperbaikinya, jadi tidak ada yang mencoba. Sebagai gantinya, kami membangun dunia kecil yang masuk akal versi kami sendiri
  • Aplikasi monolitik ini, murni karena kebutuhan, tumbuh di bagian tepinya menjadi semacam mikrokosmos aplikasi-aplikasi kecil yang bagus
  • Setiap orang yang diberi tugas memperbaiki sebagian aplikasi pada akhirnya menyerah untuk mengurai jaring laba-laba itu, lalu mencari sudut kecil yang bagus untuk membangun sesuatu yang baru. Setelah itu, perlahan mereka memperbarui tautan agar menunjuk ke hal baru yang bagus, dan membiarkan yang lama menjadi yatim
  • Ini mungkin terdengar kacau. Namun, ternyata menyenangkan sekali untuk dikerjakan. Kekhawatiran soal duplikasi kode hilang, kekhawatiran soal konsistensi hilang, dan kekhawatiran soal skalabilitas juga hilang
  • Kode ditulis untuk digunakan, ditulis agar sesedikit mungkin menyentuh area sekitarnya, dan ditulis agar mudah diganti. Kode kami menjadi decoupled karena melakukan coupling justru lebih sulit

Setelah itu

  • Sejak itu, sepanjang karier saya, saya tidak pernah lagi mendapat kehormatan bekerja pada codebase yang seaneh dan seburuk itu
  • Semua codebase buruk yang saya temui setelahnya tidak pernah berhasil melampaui kebutuhan akan konsistensi
  • Mungkin karena para developer "serius" sudah meninggalkan codebase itu sejak lama. Yang tersisa hanya intern dan junior developer yang semrawut
  • Atau mungkin karena tidak ada lapisan perantara antara developer dan pengguna. Tidak ada penerjemahan, penggalian requirement, atau kartu tugas. Yang ada hanya Anda berdiri di depan meja customer service rep dan bertanya bagaimana membuat hidup mereka lebih baik
  • Saya merindukan hubungan langsung itu. Feedback yang cepat, tidak perlunya membuat rencana besar, dan hubungan sederhana antara masalah dan kode
  • Mungkin ini hanya nostalgia naif. Namun seperti ketika saya ingin kembali ke beberapa tahun terburuk masa kecil saya, setiap kali berhadapan dengan "enterprise design patterns", pikiran saya kembali ke codebase yang indah sekaligus mengerikan itu

Opini GN⁺

  • Tulisan ini bisa memberi empati dan penghiburan bagi developer yang menangani sistem legacy. Ini menunjukkan bahwa codebase yang tidak sempurna pun tetap bernilai dan penuh pelajaran
  • Namun, masalah-masalah dalam codebase ini tidak boleh diromantisasi. Jika technical debt menumpuk, kecepatan pengembangan akan turun drastis dan maintenance menjadi sulit. Dalam jangka panjang, biayanya lebih mahal
  • Menyerah untuk memperbaiki codebase dan terus menumpuk solusi sementara bukanlah jawaban. Diperlukan strategi untuk secara bertahap memperbaiki atau memigrasikan sistem legacy
  • Budaya dan proses pengembangan juga penting. Praktik rekayasa seperti code review, perancangan arsitektur, dan dokumentasi membantu membangun codebase yang lebih baik
  • Komunikasi yang erat dengan pengguna dan feedback yang cepat adalah hal yang positif. Idealnya, ini didorong lewat metodologi seperti Agile sambil tetap menjaga kualitas kode
  • Pada akhirnya, semuanya soal keseimbangan. Daripada mengejar kesempurnaan, yang penting adalah memenuhi kebutuhan pengguna secara berkelanjutan sambil mengelola technical debt

3 komentar

 
bus710 2024-08-07

Di pekerjaan pertama saya sebagai pengembang firmware, tugas yang saya terima adalah menganalisis kode assembly yang diekstrak dari file hex MCU 8051 milik sebuah produk yang sudah tidak punya pengembang maupun source code, lalu mengimplementasikannya ulang dalam C…
Untungnya masih ada produk yang setidaknya bisa berjalan, jadi sambil melihat kodenya dan menguji produknya, entah bagaimana saya berhasil menyelesaikannya…
Saya juga pernah menerima ancaman seperti, setelah berangkat dinas ke daerah, saya harus memperbaikinya atau pulang dengan jari terpotong.
Pernah juga ada bug misterius yang ternyata penyebabnya adalah lift di balik dinding tempat perangkat itu dipasang.
Saya juga jadi teringat pernah masuk ke lokasi konferensi APEC di Dongbaekseom, Busan, sebelum pembukaan resminya untuk memasang ini-itu, haha

 
GN⁺ 2024-08-04
Opini Hacker News
  • Di perusahaan pertama, pernah memelihara aplikasi VB yang kompleks

    • Ada banyak variabel global yang disesuaikan dengan kebutuhan tiap pelanggan
    • Karena bug tidak muncul hanya saat mode debug aktif, pelanggan diajari memasang Visual Studio dan menjalankannya dalam mode debug
    • Tidak ada version control, dan kode disalin ke banyak folder sehingga membingungkan
    • Saat masalah terjadi di sisi pelanggan, kode diperbaiki langsung di lokasi
    • Tidak ada kesepakatan tentang versi final, sehingga tiap pelanggan memakai versi berbeda
  • Di pekerjaan pertama, pernah memelihara produk legacy yang ditulis dengan COBOL dan Java

    • File di source control system di-checkout satu per satu untuk dikerjakan
    • Untuk tiap pelanggan ada file jar 'master' yang mewakili produk hasil kompilasi terakhir
    • Setelah mengubah kode, skrip dijalankan untuk memperbarui file jar master
    • Codebase tidak dikompilasi secara menyeluruh dan malah dipatch secara manual
    • Banyak inkonsistensi muncul di codebase
    • Butuh 2 tahun untuk bermigrasi ke git
  • Pernah me-refactor skrip Perl dengan panjang lebih dari 12.000 baris

    • Penulis aslinya tidak mengenal array, jadi mengimplementasikan array memakai string
    • Setelah refactor, kodenya menyusut menjadi 200 baris
  • Merasakan perbedaan antara teori dan praktik

    • Banyak perusahaan dan proyek mengalami proses yang mirip
    • Metode ideal sering dibahas, tetapi pada praktiknya pekerjaan dijalankan dengan cara yang benar-benar berfungsi
  • Codebase klien Android Telegram sangat kompleks

    • Karena file-nya sangat besar, GitHub menyerah untuk merendernya
    • Semua rendering dan interaksi pesan ditangani dalam satu kelas tunggal
    • Sempat mendapat izin untuk melakukan refactor, tetapi tidak sempat dijalankan
  • Di pekerjaan pertama, pernah menyelesaikan masalah memori pada pekerjaan pelaporan

    • Team lead dan atasan terkejut
    • Developer lain membenci Linux dan ingin beralih ke .NET
  • Menyukai pengalaman berkomunikasi langsung dengan pelanggan sambil menyelesaikan masalah

    • Prototipe dibuat dengan cepat lalu pelanggan diminta mengujinya
    • Codebase berantakan, tetapi bekerja dengan baik
  • Pernah membuat sistem yang mendukung beberapa pasar

    • Sistem asli disalin untuk membuat versi internasional
    • Lima tahun kemudian, sistem-sistem itu tidak terpisah dan malah saling terjerat
    • Sistem baru dan sistem lama terikat erat satu sama lain
  • Di pekerjaan pertama, ada banyak orang yang kurang berpengalaman

    • Setelah menambah pengalaman, pindah ke tempat kerja yang lebih baik
  • Menjelaskan cara menyelesaikan masalah di SQL Server modern

    • Kustomisasi pelanggan, shared ID, tabel kalender manual, table partitioning, delayed reporting replica, dan lain-lain
    • Codebase campuran VB dan C# itu umum
    • Bisa memakai alat konversi otomatis
 
reddiana 2024-08-05

Tabel penomoran (SequenceKey) dan tabel hari kerja (Calendar)
Membangkitkan kenangan. Sekarang saya tidak tahu bagaimana caranya, tetapi dulu ini adalah tabel yang umum dipakai. Kalau mengerjakan proyek SI, fungsi terkait biasanya diimplementasikan di bagian umum lintas proses bisnis.