Ketika Feature Flag Menjadi Utang Teknis
Anda telah mengirimkan fitur dengan feature flag selama enam bulan. Setiap kemampuan baru mendapatkan flagnya sendiri. Beberapa fitur selesai diuji minggu lalu dan sekarang aktif untuk semua pengguna. Tapi flag-flag itu masih ada di kode. Sekarang basis kode Anda dipenuhi dengan cabang kondisional yang tidak ada yang ingat. Seorang pengembang baru bergabung dengan tim, membuka sebuah file, dan melihat lima pemeriksaan flag berbeda. Mana yang masih aktif? Mana yang bisa dihapus? Tidak ada yang tahu.
Ini adalah biaya tersembunyi dari feature flag. Mereka adalah alat yang ampuh untuk progressive delivery, tetapi mereka memiliki tanggal kedaluwarsa yang sering diabaikan oleh tim. Mekanisme yang sama yang memungkinkan Anda merilis dengan aman dapat menjadi beban pemeliharaan jika Anda tidak merencanakan penghapusannya.
Mengapa Flag Menumpuk
Masalahnya dimulai dengan tidak bersalah. Sebuah tim perlu mengontrol akses ke fitur baru selama pengujian. Mereka menambahkan sebuah flag. Fiturnya berfungsi, jadi mereka meluncurkannya ke lebih banyak pengguna. Kemudian mereka beralih ke proyek berikutnya. Flag itu tetap ada di kode karena menghapusnya terasa seperti pekerjaan ekstra tanpa manfaat langsung.
Seiring waktu, basis kode dipenuhi dengan kondisi mati. File konfigurasi bertambah panjang. Dasbor platform menunjukkan puluhan flag, tetapi setengahnya diaktifkan secara permanen. Setiap deployment membawa kompleksitas yang tidak perlu. Ketika sesuatu rusak, pengembang membuang waktu menelusuri logika flag yang tidak lagi penting.
Penyebab utamanya sederhana: tim fokus pada pembuatan dan pengaktifan flag tetapi lupa bahwa setiap flag memiliki siklus hidup. Sebuah flag lahir, ia menjalankan tujuannya, dan kemudian ia harus mati. Tanpa rencana untuk langkah terakhir itu, flag menjadi utang teknis yang bertambah dengan setiap rilis.
Siklus Hidup Sebuah Feature Flag
Feature flag yang sehat melalui tahapan yang jelas. Ini dimulai ketika tim memutuskan untuk membuatnya. Pada saat itu, seseorang harus mencatat tujuan flag: fitur apa yang dikendalikannya, siapa yang dapat mengaktifkan/menonaktifkannya, dan kapan harus dihapus. Metadata ini mungkin tampak seperti beban tambahan, tetapi menjadi penting berminggu-minggu kemudian ketika tim perlu memutuskan flag mana yang akan dibersihkan.
Setelah dibuat, flag bergerak melalui fase peluncuran. Pertama, ini mengaktifkan fitur untuk pengujian internal. Kemudian untuk persentase kecil pengguna. Kemudian untuk semua orang. Pada tahap akhir, fitur tersebut tidak lagi eksperimental. Itu adalah bagian dari aplikasi. Flag tidak memiliki alasan untuk ada.
Di sinilah sebagian besar tim gagal. Mereka mencapai tahap "semua pengguna" dan berhenti memikirkan flag tersebut. Fiturnya berfungsi. Tim beralih. Flag tetap ada di kode, diam-diam menambah kompleksitas.
Diagram berikut merangkum empat tahap kunci dan tindakan yang memindahkan flag dari satu tahap ke tahap berikutnya.
Dua Praktik yang Mencegah Pembusukan Flag
Mencegah akumulasi flag membutuhkan dua hal: proses pembersihan terjadwal dan cara mendeteksi flag basi.
Jadwalkan Pembersihan ke dalam Siklus Pengembangan Anda
Jadikan penghapusan flag sebagai bagian rutin dari alur kerja Anda. Di akhir setiap sprint, tinjau daftar flag yang telah aktif untuk semua pengguna selama lebih dari dua minggu. Hapus flag tersebut dari kode dan dari platform manajemen flag Anda. Jika sebuah flag tidak dapat dihapus karena masih diperlukan untuk pengujian A/B atau fitur yang belum selesai, perbarui metadatanya dengan tanggal penghapusan yang diharapkan baru.
Ini kedengarannya sederhana, tetapi membutuhkan disiplin. Tim yang melewatkan langkah ini untuk satu sprint sering melewatkannya untuk sprint berikutnya. Tidak lama kemudian, backlog pembersihan tumbuh lebih besar dari yang ingin ditangani siapa pun.
Deteksi Flag Basi Secara Otomatis
Tinjauan manual saja tidak cukup. Anda memerlukan deteksi otomatis. Banyak platform feature flag dapat menandai entri yang belum dimodifikasi atau diperiksa dalam periode tertentu. Jika platform Anda tidak mendukung ini, tulis skrip sederhana yang membaca konfigurasi flag dan membandingkannya dengan stempel waktu modifikasi terakhir. Flag yang tidak tersentuh selama berminggu-minggu dan diaktifkan untuk semua pengguna adalah kandidat utama untuk dihapus.
Beberapa tim melangkah lebih jauh dengan menambahkan langkah linting ke pipeline CI mereka. Linter memeriksa flag yang telah berada di basis kode lebih lama dari ambang batas yang dikonfigurasi dan memperingatkan pengembang. Ini menangkap flag basi sebelum mereka menjadi perlengkapan permanen.
Sebagai contoh, skrip berikut mencari nama flag dalam kode sumber dan menanyakan API manajemen flag untuk melihat apakah flag tersebut diaktifkan secara permanen untuk semua pengguna:
#!/bin/bash
FLAG_NAME="MY_FLAG"
# Hitung kemunculan dalam kode sumber
OCCURRENCES=$(grep -r "$FLAG_NAME" src/ --include='*.js' | wc -l)
# Tanyakan API manajemen flag untuk status
STATUS=$(curl -s "https://flags.example.com/api/flags/$FLAG_NAME" | jq -r '.status')
# Jika flag diaktifkan secara permanen dan jarang direferensikan, tandai
if [ "$STATUS" = "permanently_enabled" ] && [ "$OCCURRENCES" -gt 0 ]; then
echo "PERINGATAN: Flag $FLAG_NAME diaktifkan secara permanen tetapi masih digunakan di $OCCURRENCES tempat."
echo "Pertimbangkan untuk menghapusnya dari kode dan konfigurasi."
fi
Mengapa Pembersihan Penting Lebih dari Sekadar Kebersihan Kode
Membersihkan feature flag bukan hanya tentang menjaga basis kode tetap rapi. Ini tentang menjaga kepercayaan tim pada sistem. Ketika pengembang tidak yakin apakah sebuah flag masih digunakan, mereka menjadi takut untuk menghapusnya. Mereka khawatir bahwa beberapa dependensi yang tidak diketahui mungkin rusak. Jadi flag itu tetap ada, dan konfigurasi menjadi semakin kompleks. Semakin lama flag itu ada, semakin sulit untuk dihapus, karena tidak ada yang bisa melacak semua tempat di mana flag itu mungkin penting.
Erosi kepercayaan ini memiliki konsekuensi nyata. Fitur baru membutuhkan waktu lebih lama untuk diimplementasikan karena pengembang harus bekerja di sekitar logika flag lama. Debugging menjadi lebih lambat karena setiap cabang kondisional harus dievaluasi. Memperkenalkan anggota tim baru menjadi lebih sulit karena mereka harus mempelajari sejarah setiap flag sebelum dapat berkontribusi.
Siklus hidup flag yang bersih mengembalikan kepercayaan itu. Ketika setiap flag memiliki tujuan yang diketahui dan tanggal penghapusan yang direncanakan, pengembang dapat percaya bahwa kode yang mereka lihat adalah kode yang penting. Mereka dapat menghapus flag tanpa rasa takut. Mereka dapat fokus membangun fitur baru daripada menguraikan eksperimen lama.
Daftar Periksa Praktis untuk Manajemen Siklus Hidup Flag
- Catat tujuan, pemilik, dan tanggal penghapusan yang diharapkan saat membuat flag baru.
- Tinjau semua flag di akhir setiap sprint. Hapus yang aktif untuk semua pengguna selama lebih dari dua minggu.
- Gunakan alat otomatis untuk mendeteksi flag yang belum dimodifikasi atau diperiksa baru-baru ini.
- Tambahkan langkah linting CI yang memperingatkan tentang flag yang lebih tua dari ambang batas yang dapat dikonfigurasi.
- Perbarui metadata flag ketika tanggal penghapusan berubah. Jangan biarkan tanggal melayang tanpa pengakuan.
- Hapus flag dari kode dan konfigurasi. Flag yang tersisa di konfigurasi masih merupakan kewajiban.
Intisari
Feature flag tidak bersifat permanen. Perlakukan mereka seperti perancah sementara: pasang saat Anda membutuhkannya, turunkan saat struktur berdiri sendiri. Flag yang tetap berada di kode setelah fiturnya dirilis sepenuhnya bukanlah jaring pengaman. Itu adalah beban mati. Rencanakan penghapusan dari hari pertama, dan pipeline progressive delivery Anda akan tetap ramping, cepat, dan dapat dipercaya.