· kaynak Hacker News – Front Page (native)
Deser, Serde'a olay güdümlü bir alternatifle Rust'ta serileştirmeyi yeniden düşünüyor
2022'deki bir deney olarak başlayıp yeniden gündeme gelen Deser, Rust serileştirmesini olay güdümlü sink'ler ve heap'te tutulan state üzerine kuruyor; Serde'ın en derin tasarım sınırlarından kurtulmak pahasına self-describing olmayan formatlardan vazgeçiyor.

2022'de bir deney olarak başlayıp yakın zamanda yeniden ele alınan Rust serileştirme kütüphanesi Deser, yazarının dikkat çekmeyi hak ettiğini düşündüğü bir noktaya geldi. Armin Ronacher'ın 29 Eylül'de lucumr.pocoo.org blogunda yayımladığı ve Hacker News'in ana sayfasına ulaşan yazıda, Serde'ın en kalıcı sorunlarının tasarımından ve stabilite garantilerinden kaynaklandığını, Deser'ın ise Serde'ın kullanıcı deneyimini korurken altındaki mekanizmayı değiştirdiğini savunuyor. Ronacher, Sentry'de geçirdiği yıllarda, devasa hacimde güvenilmeyen JSON işleyen Relay servisi üzerinde çalışırken aynı Serde sorunlarının tekrar tekrar karşısına çıktı. Adı da bunu yansıtıyor: Deser, Serde'ın iki yarısının yer değiştirmiş hali.
Yeniden yazımı tetikleyen üç uç durum
Yazı üç örnekle açılıyor. İlk örnekte, serde_'ın isteğe bağlı arbitrary_precision özelliği etkinleştirildiğinde internally tagged bir enum başarısız oluyor. Serde'ın veri modelinde rastgele hassasiyetli sayılara yer olmadığından format bunları sihirli bir anahtara sahip bir map olarak kaçakça taşıyor; tagged enum'lar etiket gelene kadar alanları buffer'da tutmak zorunda ve buffer bu sihirli anahtardan habersiz. Böylece tamamen geçerli bir radius değeri "invalid type: map, expected f64" hatasıyla reddediliyor — ve Cargo özellikleri birleştirdiği için, bağımlılık grafiğindeki herhangi bir crate'in bu özelliği açması bile hatayı tetiklemeye yetiyor.
İkinci örnek #[serde(flatten)] ile ilgili. Bir HashMap<u32, u32> tutan struct kendi başına deserialize edildiğinde JSON string anahtarlarını tam sayıya çeviriyor; ancak değer flatten'ın buffer'ından geçtiğinde "42" anahtarı düz string olarak kalıyor ve parse başarısız oluyor. Hata ayrıca sorumlu anahtarı değil, dokümanın sonunu işaret ediyor.
Üçüncü örnek birleştirilebilirlik. Bir fonksiyon type parameter olarak geçirilemediği için, from_hex gibi bir deserialize_with adapter'ı Option, Vec veya map'in içine ulaşamıyor. Her container için ayrı bir wrapper fonksiyon yazıyorsunuz ve #[serde(default)] eklemeyi hatırlamazsanız alan artık isteğe bağlı olmaktan çıkıyor.
Yazıya göre bunlar basitçe yamalanabilecek bug'lar değil: Serde'ın tasarımının sonucular ve bu tasarım, her formata ve elle yazılmış her implementasyona verilen stabilite sözleriyle kilitlenmiş durumda.
Acının arkasındaki üç karar
Ronacher tekrarlayan sorunları üç temel karara bağlıyor. Serde, JSON, YAML ve TOML gibi self-describing formatlarla, okuyucunun type'ı baştan bilmesi gereken postcard, bincode veya protobuf gibi formatlar için tek bir trait kümesi kullanıyor; bu genişlik yararlı, ancak formata bağlı özellikler sınırlarını yalnızca runtime'da belli ediyor ve derive edilmiş bir struct, object beklenirken JSON array'ini sessizce kabul ediyor. Serde'ın sabit veri modeli, internally tagged enum'lar, untagged enum'lar veya flatten değerleri buffer'a aldığında bilgi kaybediyor; hataların konumunu yitirmesinin ve ekosistem uzantılarının in-band sinyale başvurmasının nedeni de bu. Ve deserialization çağrı stack'i üzerinde rekürsif olarak ilerliyor: her iç içe seviye stack alanı tüketiyor, recursion limitleri yalnızca bazı kod yollarını koruyor ve derin iç içe veri, limiti olmayan yazma ya da dinamik değer yolları üzerinden bir süreci çökertebiliyor. Rekürsiyon ayrıca bir deserialization'ın daha fazla girdi beklerken duraklatılamaması anlamına geliyor.
Deser modeli nasıl tersine çeviriyor
Serde'da type sürücüdür: bir Deserialize implementasyonu deserializer'dan beklediği değerin türünü ister ve format bir visitor'a geri çağrı yapar, her seviyede rekürsif olarak iner. Deser bunu tersine çevirir. Format sıradaki değeri duyurur ve olayları bir sink'e iter; bir sink iç içe bir değerle karşılaştığında ona rekürsif olarak girmez, yeni bir sink'i bir driver'a devreder ve tüm state heap'te bir arena'da tutulur. Emitter'lar iç içe değerlere inmek yerine çıkış yolunda döndürür. Trait tasarımı başlangıçta dtolnay'ın miniserde'sinden esinlenmişti; bu da runtime reflection üzerine kurulan ya da binary formatlara yönelik yeni veri modelleri hedefleyen önceki denemelerden biriydi.
Bu tersine çevirmenin bilinçli bir bedeli var: Deser, protobuf gibi self-describing olmayan formatları destekleyemiyor ve bunları tasarımın tamamen dışında bırakıyor. Yazının çerçevesiyle, Serde'ı düzeltmek başka uzlaşmaları kabul etmek anlamına geliyor.
Serde'ı tahtından etmek için neler gerekiyor
Ronacher, Serde'ın tahtından edileceğini beklemiyor — orphan rule onu ekosisteme derinlemesine yerleştirmiş durumda — bu yüzden Deser, bir crate yazarının kontrol edebildiği şey üzerinden yarışıyor: tamlık. YAML, JSON, TOML, CBOR, JSON5, XML ve plist dahil olmak üzere başlıca self-describing formatları implement ediyor; XML özellikle Serde'ın kendisinin desteklemeyi reddettiği bir format. Tradeoff'lar somut. Compile süreleri Serde'dan bir miktar iyi, binary şişmesi epey kötü ve runtime performansı karışık — genel olarak kabaca karşılaştırılabilir, ancak bazı format yapılarında ciddi kayıplar var. Yazının hükmü şu: Deser, bu tradeoff'ların uygun düştüğü yerlerde artık ilke olarak drop-in bir alternatif.
Neden önemli
Serde, Rust ekosisteminin yük taşıyan altyapısı ve sınırları JSON, YAML veya TOML'a dokunan her crate'in davranışını şekillendiriyor. Deser, tanıdık derive tabanlı deneyimin olay güdümlü, heap tabanlı bir çekirdek üzerinde durabileceğini gösteriyor; bilgi kaybeden buffer'lama, güvenilmeyen girdide stack tükenmesi, birleşemeyen adapter'lar gibi — Serde'ın stabilite garantilerinin erişilmez kıldığı bütün bir sorun sınıfının etrafından dolanıyor. Serde'ın yerini almasa bile bu deney, aynı zamanda tasarım uzayının bir haritası ve baskın aracın kısıtlarının yasa değil tercih olduğu anısının bir hatırlatıcısı.
- #rust
- #serialization
- #serde
- #deser
- #libraries