Sonuç (Conclusion)
PyO3'ün Rust'ın lifetime kullanan struct'larını doğrudan Python'a açamaması ilk bakışta bir sınırlama gibi görünebilir. Ancak Rust standart kütüphanesi ve PyO3, bu sınırlamayı aşmak için güçlü araçlar sunar. std::mem::take ve std::mem::replace, değiştirilebilir referanslar (mutable reference) ile sahip olunan değerleri (owned value) ustalıkla ele almayı sağlar; Arc ve Mutex ise paylaşılan değiştirilebilir veriyi Python'a açmak için son derece kullanışlıdır. Özellikle PyO3'ün MutexExt aracı, Python ile birlikte mutex kullanırken deadlock'u önlemek için vazgeçilmezdir.
Ana noktaların özeti
Bu belge, Django'nun şablon dilini Rust ile yeniden uygulayan bir projede Rust ile Python arasında değiştirilebilir (mutable) veri paylaşılırken karşılaşılan teknik sorunları ve bunların çözüm sürecini adım adım açıklar.
-
Arka plan: Django şablon dili, şablona dinamik veri sağlamak için
contextadlı bir nesne kullanır. Projenin Rust uygulamasında bucontext, bir Rust struct'ı olarak tanımlanmıştır ve şablon etiketleri render edilirken değiştirilebilir referans (&mut Context) olarak geçirilmelidir. -
İlk sorun: Rust kodundaki değiştirilebilir referansın (
&mut Context) özel etiket çalıştırma için Python fonksiyonuna geçirilmesi gerekir. Ancak Python, Rust'ın lifetime kavramını anlamaz ve Rust-Python entegrasyon kütüphanesi PyO3 sahipliği olan değerler (owned value) ister; bu nedenle referansı doğrudan geçirmek derleme hatasına yol açar. -
Çözüm süreci:
- Sahiplik sorununu çözme:
std::mem::takekullanılarak&mut Contextiçinden sahiplik geçici olarak alınır ve Python'a aktarılabilen sahipli birContextnesnesi oluşturulur. Python kodu çalıştıktan sonra işlenmişContext'i yeniden özgün referans konumuna koymak içinstd::mem::replacekullanılmaya çalışılır. - 'Moved Value' hatasını çözme: Ancak bu süreçte,
Contextnesnesi Python fonksiyonuna move edildikten sonra yeniden kullanılmak istendiğinde "use of moved value" derleme hatası ortaya çıkar. Bunu çözmek içinArc(Atomic Reference Count) eklenerekContextbununla sarılır. Böylece sahiplik taşınmadan Python'a klonlanmış bir referans (clone) geçirilebilir. - Python referansı elinde tutmaya devam ederse: Python
Contextreferansını tutmaya devam ederse,Arc::try_unwrapile sahipliği geri alma işlemi başarısız olabilir. Bu durumda,Contextiç verisini deep copy edenclone_refgibi bir fallback metodu uygulanarak veri kopyalanır. - Python'da veri değişikliğine izin verme: Son aşamada, Python kodunun
Context'i yalnızca okuması değil değiştirebilmesi içinMutexeklenir.Arc<Mutex<Context>>yapısı kullanılarak veriye birden çok thread'den güvenli biçimde erişilmesi ve verinin değiştirilmesi sağlanır. Bu sırada Python yorumlayıcısıyla deadlock yaşanmaması için PyO3'ün sunduğuMutexExtiçindekilock_py_attachedmetodu kullanılır.
- Sahiplik sorununu çözme:
Henüz yorum yok.