Peringatan Longrid: Anda telah diperingatkan, banyak surat.
Telah lama mengembangkan format distribusi untuk aplikasi yang "bebas" dari dependensi seluruh sistem. Ubuntu sangat, sangat aktif dalam mempromosikan snap-nya, gnome-flatpack. Keduanya menjanjikan surga dan kebebasan dari rpm / deb. Mari kita pikirkan masalah yang ingin mereka selesaikan, dan harga yang mereka minta solusi untuk masalah ini.
Perpustakaan
Tidak seorang pun di dunia modern dapat menulis aplikasi tanpa menggunakan kode orang lain. Ada beberapa alasan:
- Banyak perpustakaan sangat serius sehingga menulis fungsi mereka dari awal adalah tugas yang menakutkan. Contoh - dukungan untuk unicode, rendering font, matematika.
- Perpustakaan lain menawarkan serangkaian fungsi yang agak sederhana, tetapi mereka ditulis dengan sangat baik sehingga menulis setidaknya dengan sangat baik hampir tidak mungkin. Perpustakaan standar bahasa pemrograman, berbagai implementasi libc, dll.
- Biaya bekerja dengan kode orang lain (yang dikhususkan untuk bagian ini) seringkali lebih rendah daripada biaya pemeliharaan kode Anda. Kepadatan "bug per baris kode" cenderung sebanding, dan Anda harus menangkap sendiri bug Anda. Pustaka asing (populer) kemungkinan akan didebug dan diperbaiki oleh tangan yang salah.
Kuncinya adalah bahwa bahkan jika kita dapat menulis fungsionalitas pustaka tunggal sendiri dari prinsip, jumlah total fungsi yang diperlukan (dan dependensi) memberikan peningkatan yang hampir eksponensial dalam jumlah tugas yang perlu diselesaikan, menunda waktu mulai bekerja pada kode program itu sendiri. ke jarak yang tidak terjangkau.
Contoh untuk mewujudkan skala drama: katakanlah aplikasi Anda menggunakan dua baris input sebagai argumen opsional dan menampilkannya bersama setelah normalisasi. Jika Anda menulis aplikasi industri (aplikasi yang terlihat "asli"), maka:
- Anda memerlukan pengurai baris perintah
- Yang seharusnya menerima unicode
- Dan mungkin memberi petunjuk kepada pengguna bahwa ia telah menyegel nama argumen
- Yang membutuhkan perbandingan fonetis
- Dan mungkin ekspresi reguler
- Secara umum, Anda harus mendukung tidak hanya Unicode, tetapi juga lokal lain, yang memerlukan pustaka dukungan lokal dan SEMUA yang dibuat orang dalam konteks lokal.
- Rangkaian string dengan normalisasi adalah penggunaan lain dari pustaka Unicode yang terpisah; Anda sendiri tidak menerapkan ini.
- Output ke layar (bantuan pada baris perintah, hasil Anda) cenderung membutuhkan dukungan untuk ncurses - perpustakaan yang mendukung terminal yang berbeda (Anda dapat melakukannya dengan mode teks, tetapi aplikasi sering menggunakan kemampuan warna).
- Tes melibatkan penggunaan kerangka uji, mungkin perpustakaan untuk ngengat.
Jelaslah bahwa kerumitan seperti itu untuk tugas "dua-baris" adalah rekayasa berlebihan, tetapi begitu Anda mulai melakukan sesuatu yang lebih, gagasan "semuanya sendiri" mulai melampaui batas-batas yang dapat diamati dan direalisasikan.
Menurut Anda, berapa banyak perpustakaan yang diperlukan untuk menjamin bahwa ikal http: // ... akan berfungsi? Banyak. Anda akan menggunakannya, tetapi dependensi dependensi Anda adalah dependensi Anda.
Copypaste & Membatalkan VS tautan dinamis
Sementara penggunaan perpustakaan tidak bisa dihindari, penggunaan itu sendiri dapat bervariasi dalam implementasinya. Harap perhatikan bahwa kami memiliki dua kata penting: "gunakan" dan "implementasi penggunaan". Apa artinya menggunakan? Dalam bentuknya yang paling kasar - kemampuan untuk memanggil kode perpustakaan bila perlu. Dan inilah implementasi dari ini:
- Kita dapat menyalin kode yang melakukan operasi yang kita butuhkan. Dalam bentuk potongan kode (copy & paste), sebagai modul terpisah dalam bahasa pemrograman (file objek untuk bahasa yang dikompilasi), atau sebagai modul terpisah (untuk bahasa yang ditafsirkan). Di suatu tempat tepat di sebelahnya adalah "salin file sumber perpustakaan ke direktori Anda dengan aplikasi." Masalah apa yang terjadi? Masalah utama, utama adalah bahwa kita kehilangan (selamanya) koneksi dengan aslinya. Bahkan jika penulis perpustakaan asli mengoreksi kesalahan, kami tidak akan mengetahuinya. Selain itu, jika kita hanya menyalin kode, maka orang berikutnya yang bekerja pada program ini bahkan tidak akan dapat mengetahui bahwa kode ini adalah "alien". Bahkan, kami memotong jalan dalam pertanyaan "menulis dari awal" dan mengambil milik orang lain. Namun, kami hanya memotong sepotong, karena jika ada kesalahan dalam kode ini (tetapi mereka tidak akan ada di sana , mereka ada di sana ), maka koreksi mereka akan membutuhkan yang benar untuk pergi dan memahami esensi masalah ke bagian paling bawah. Sekalipun uji coba mengharuskan membaca beberapa ratus ribu baris kode sumber dan ratusan RFC (serta komentar bahwa implementasi berbeda dari RFC), kami tidak punya cara lain. Kesalahan utama di tempat ini adalah kami telah kehilangan informasi bahwa kode ini asing. Memiliki komentar dalam file dapat membantu, tetapi membutuhkan keterlibatan aktif dan mendalam seseorang, karena jika kita menulis dalam komentar "diambil dari libfoobar, src / lib / foo.c versi 364a51577f3782dbf8e5d2482ab941980357c492", maka seseorang perlu melihat di mana libfoobar berada, versi apa itu dan apa yang telah berubah dari versi sebelumnya. "Untuk menyederhanakan proses ini, kita perlu meta-informasi yang dapat dibaca mesin.
- Jika kami menemani "kode orang lain" dengan meta-informasi dan menggunakan program untuk mengelola kode ini (bukan salin-tempel), maka ini disebut vending , mis. dimasukkannya terkendali kode orang lain dalam kode Anda. Secara teknis, penjual dapat terjadi pada tahap teks sumber, menghubungkan objek ke file yang dapat dieksekusi, mengimpor modul (dalam interpreter) dari aplikasi, atau bahkan menghubungkan dinamis dengan versi perpustakaan "Anda" (lebih lanjut tentang ini nanti).
- Akhirnya, kita dapat melakukan penautan dinamis pada tahap peluncuran aplikasi. Untuk bahasa yang dikompilasi, ini biasa saja, untuk bahasa yang ditafsirkan, ada modul dalam impor seluruh sistem. Jika beberapa aplikasi dapat mengimpornya, maka ini adalah perpustakaan bersama. Jika aplikasi "membawa modulnya", maka pustaka adalah "miliknya", meskipun antarmuka tersebut menyiratkan "pustaka bersama". Misalnya, jika suatu aplikasi menggunakan versi miliknya sendiri, terlepas dari apakah itu berbeda dari yang umum atau tidak, maka ini adalah vending. Dan jika sistem diimpor, maka ini adalah perpustakaan bersama.
Apa perbedaan antara metode ini? Saya akan memberikan argumen singkat, mereka telah dibahas berkali-kali di banyak artikel. Masing-masing argumen ini tetap valid meskipun ada kontra-argumen yang bertetangga:
- Menyimpan memori (RAM dan disk) untuk itu, mengurangi ukuran sistem yang diinstal. Semakin banyak aplikasi yang menggunakan hal yang sama, semakin besar penghematan memori. Dengan demikian, sebaliknya, semakin banyak "Anda" membawa aplikasi perpustakaan, semakin "gemuk" itu.
- Debat tentang siapa yang memantau kerentanan adalah sistem (menyediakan pembaruan perpustakaan) atau penulis aplikasi (memperbaruinya tepat waktu).
- Penyelesaian konflik dependensi (penjual memecahkan masalah ini karena perpustakaan bersama memerlukan perhatian dan ketepatan dari semua peserta dalam proses, kadang-kadang menciptakan kesulitan yang tak dapat diatasi), neraka dll legendaris yang sama.
- Versi baru perpustakaan - baik itu muncul atas permintaan penulis aplikasi, atau dengan keputusan penulis distribusi. Dalam satu kasus, penulis dapat membawa fitur baru yang ia butuhkan, dalam kasus lain, distribusi dapat membawa peningkatan pada aplikasi yang ada dengan mendukung sesuatu yang baru di perpustakaan (misalnya, layar hidpi mulai bekerja dengan benar di semua aplikasi yang secara dinamis terhubung ke perpustakaan qt / gtk) .
Semua masalah ini telah ditangani berkali-kali sebelumnya. Sebaliknya, saya ingin fokus pada aspek sosial dari DAS "milikku" dan "semua umum".
Kontrak Sosial dan Pemelihara Tenaga
Perpustakaan bersama adalah kerja sama, kekuatan, dan tanggung jawab. Orang-orang yang menentukan perpustakaan bersama mana yang tersedia dalam sistem operasi menentukan kepada produsen perangkat lunak perpustakaan bersama apa yang dapat mereka gunakan. Banyak perangkat lunak dapat menggunakan pustaka yang berbeda, dan indikasi versi yang tepat untuk digunakan diserahkan pada kebijaksanaan linker (untuk bahasa yang dikompilasi) atau penangan file ketergantungan (pip, bundler, dll). Jika semua aplikasi dalam distribusi dibangun dengan persyaratan yang sama, maka rahmat datang: jika ada kesalahan di beberapa perpustakaan, pemelihara perpustakaan ini memperbarui versi, dan perbaikannya secara otomatis diterapkan ke semua aplikasi. Bahkan jika aplikasi dirilis setiap dua tahun, perbaikan di openssl bersyarat akan diterapkan dalam seminggu. Jika dalam OS tertentu keputusan telah dibuat untuk meninggalkan protokol lama, beberapa modifikasi (misalnya, antarmuka pengguna), maka perubahan ini juga akan berlaku untuk semua orang. Terlihat & rasakan dalam gaya umum yang (mungkin) dapat diubah oleh pengguna untuk selamanya. Apakah ini bukan rahmat?
Kekuasaan dan perjuangan untuk itu
... Rahmat ini mengharuskan semua aplikasi dapat bekerja dengan versi perpustakaan yang dipilih. Tetapi bagaimana jika beberapa aplikasi menginginkan fungsi yang sangat, sangat baru dari perpustakaan, dan semua aplikasi lain tidak ingin menggunakannya, karena ini, misalnya, bukan rilis LTS dari perpustakaan, yaitu. apakah itu tidak cukup stabil? Tetapi kit distribusi mungkin menolak untuk beralih ke versi baru "di luar prinsip", karena kami berjanji pengguna hanya memperbaiki bug, dan versi baru hanya di versi OS berikutnya, yang (seperti) akan dirilis dalam waktu setengah tahun. Dan ini menyebabkan penolakan dari penulis aplikasi. Dengan siapa Anda memberi tahu saya versi apa yang harus saya pakai? Saya seorang penulis, saya melihatnya seperti itu. Saya perlu libfoobar 3.14-pre2 atau lebih, bukan libfoobar kuno Anda yang membosankan 3.10.
... Pada titik ini, penulis cukup menulis di persyaratan aplikasi libfoobar>=3.14-pre2
. Pemelihara menerima dan menambal permintaan, ditambah menghapus kode yang bergantung pada pustaka ini. Mungkin Atau hanya menolak untuk menerima versi baru dengan ketergantungan seperti itu sampai ketergantungan ini (libfoobar 3.16) ada di versi distribusi yang baru.
Jika penulis benar-benar membutuhkan pengguna untuk menggunakan versi baru (misalnya, karena penulis tidak ingin mendukung versi lama), maka ia mencari solusi untuk mengirim aplikasi ke pengguna.
Hal yang sama terjadi ketika ada beberapa distribusi, ada yang lebih baru, ada yang lebih tua. Mempertahankan distribusi yang lebih lama, pengujian dengan perpustakaan yang berbeda sulit. Jadi opsi "kirim bersama perpustakaan Anda" muncul segera.
Tragedi komunitas
Ini menciptakan prasyarat munculnya tragedi komunitas:
- Setiap produsen (pembuat perangkat lunak) ingin mengirimkan sesuai kebutuhan. Menyesuaikan dengan aturan orang lain (versi) adalah buang-buang waktu dan usaha, terlebih lagi karena ada banyak distribusi yang berbeda di dunia
- Pengguna menginginkan versi baru.
Pada saat yang sama, semakin banyak aplikasi datang dengan perpustakaan mereka, semakin sedikit penggunaan perpustakaan sistem. Ingat rahmat? Semakin sedikit "universal," semakin sedikit rahmat. Jika perpustakaan bersama digunakan oleh 5 aplikasi berbeda dari 995 yang lain, maka manfaat perpustakaan ini adalah 0,5%. Sayang sekali, ya. Selain itu, itu menyakiti semua pengguna, bahkan mereka yang, pada prinsipnya, tidak memiliki kebutuhan akut untuk fitur baru - tetapi jika aplikasi hanya tersedia dalam bentuk penjual otomatis, maka pengguna tidak memiliki pilihan.
Ternyata kami memiliki ekstrem global: semua aplikasi hanya menggunakan pustaka bersama (rahmat umum maksimum, ketidaknyamanan bagi penulis aplikasi individual) atau "masing-masing dengan sendirinya" (distribusi yang tebal, dengan sekelompok aplikasi yang mungkin memiliki kerentanan yang tidak terdeteksi tetapi banyak digunakan,) memakan banyak memori, tetapi penulis setiap aplikasi nyaman).
Di sinilah kita datang ke sengketa rpm / deb VS snap / flatpack
Kebebasan atau perbudakan?
Ubuntu sangat, sangat sangat mendukung snap'y. GNOME yakin bahwa masa depan ada dalam flatpack. Masing-masing dari mereka adalah kerangka kerja untuk aplikasi yang sangat individualistis. Semua jenis elektron, yang ada pada mereka tidak hanya kap engine engine, tetapi juga sistem operasi engine engine. Libc sendiri, libssl sendiri, regexp sendiri, ncurses sendiri, dll. Hanya inti yang bertindak seperti biasa, yaitu sebenarnya, ini adalah aplikasi kemas yang sama, tetapi untuk desktop. Berikan masing-masing inti Anda sendiri, dan Anda mendapatkan alat dalam bentuk mesin virtual. Tambahkan metadata - dan Anda mendapatkan wadah Docker.
Individualisme aplikasi (penulis aplikasi) dapat dimengerti, tetapi siapa yang kemudian berdiri untuk kebaikan bersama? Peningkatan lokal utama diimbangi oleh sedikit degradasi distribusi umum dikalikan dengan aplikasi murni. Jika setiap orang membuat perbaikan lokal untuk diri mereka sendiri, maka jumlah penurunan nilai menjadi lebih besar daripada manfaat dari jumlah perbaikan.
Tampaknya di tempat ini pencipta distribusi harus bertindak sebagai penjaga kepentingan bersama. Namun ...
Politik
Ubuntu tergantung pada Debian lebih dari yang diinginkan Canonical (perusahaan Ubuntu). Nilai Ubuntu bukan dalam upaya pengelola Ubuntu, tetapi dalam repositori perangkat lunak besar yang berasal dari Debian dalam bentuk di mana semua aplikasi bekerja dengan baik bersama melalui upaya ribuan pengelola paket individu yang memiliki distribusi Debian. Canonical menambahkan di atas ini upaya untuk memoles hasilnya - dan untuk ini dicintai oleh beberapa orang. Tambahkan sedikit pemasaran dan siklus hidup tetap, yang sesuai dengan keinginan perusahaan, dan kami mendapatkan produk yang hebat.
... Yang tergantung pada kehendak ribuan sukarelawan di suatu tempat di luar sana.
Yang tidak sesuai dengan hampir semua perusahaan komersial. Bagaimana cara menghentikan kecanduan ini? Itu benar dengan membuat bundel aplikasi Anda sendiri. Semakin banyak aplikasi, semakin sedikit keuntungan di hulu akan merugikan perusahaan. Cukuplah untuk mengingat cerita ketika pemungutan suara di Debian pada systemd mengubur pemula, yang dikembangkan oleh Canonical.
Tetapi Pertahankan beberapa puluh ribu aplikasi, beberapa di antaranya adalah ruang mereka sendiri (erlang, go, perl, python, R, julia, dll), dan beberapa adalah monster di area subjek yang sesuai (browser, emacs, tex, alat pacu jantung, dll) - ini adalah kerja berat. Tidak heran ini adalah ribuan pemelihara.
... Dan ada sebuah ide. Dan, biarkan, penulis aplikasi itu sendiri. Menjaga aplikasi. Mari kita beri semua orang kotak pasir, biarkan mereka menggali. Penulis mendapatkan kebebasan, aplikasi Canonical - yang tidak bergantung pada Debian dan yang setidaknya dipelihara seseorang secara gratis. Pengguna mendapatkan ...
... aplikasi yang gemuk, berat, yang pembaruannya tidak teratur dan yang dapat dengan mudah membuat kerentanan tidak diperbaiki selama bertahun-tahun ... Tetapi beberapa di antaranya baru mengkilap.
Jadi apa selanjutnya?
Bayangkan sebuah dunia di mana semua orang membawa semuanya ... Apakah Anda tahu tampilannya? Lihatlah chefsdk. Dia mengirimkan dirinya di dalam postgresql (dengan dependensinya), rabbitmq (yang tergantung pada erlang-nya), ditambah chef-server juga pada erlang, jadi dia juga memiliki erlang sendiri. Tiba-tiba, kami memiliki dua erlangs dan puluhan salinan perpustakaan yang sama di dalam aplikasi yang sama, sedikit berbeda dalam versi. Ini bukan opsi terakhir, karena di dalam, masih ada perpustakaan umum antara komponen. Jika kita memotongnya lebih jauh, kita mendapatkan beberapa lusin salinan openssl dan libc untuk satu aplikasi. Bahkan dalam bentuk akhir, sepertinya 600MB per aplikasi.
... Yang, tentu saja, merupakan kelipatan dari aplikasi elektron rata-rata ... Dan 12 kali lebih besar dari keseluruhan server mariadb (seluruh DBMS!), Atau krita atau gimp (aplikasi grafis besar).
Dan apakah semua orang akan seperti itu? Saya memiliki 2000 paket yang diinstal di komputer saya (tidak termasuk -dev dan lib) ... 2000 * 300 = 600GB (Untuk ukuran rata-rata yang dihasilkan, saya mengambil setengah dari chefsdk, karena tidak semua orang begitu mengerikan oleh ketergantungan). Sekarang mereka menempati sekitar 7GB (termasuk sumber daya, seperti dokumentasi, editor tekstur, templat CAD, dll.).
Jika ini berubah menjadi 600GB, bukankah itu benar-benar sebuah tragedi komunitas? Dalam setiap momen yang diambil, kami mengamati pengoptimalan lokal (dan solusi ketidaknyamanan orang lain), tetapi bersama-sama, jumlah dari pengoptimalan lokal ini mengurangi keseluruhan optimalitas sistem. Menurut pendapat saya, lebih dari keuntungan lokal masing-masing peserta.
Saya mengerti mengapa Canonical push snap. Saya mengerti ini, dan tidak menyetujui.