3 puan yazan GN⁺ 2024-07-05 | 1 yorum | WhatsApp'ta paylaş
  • Firezone, Rust kullanarak Android telefonlar, macOS bilgisayarlar veya Linux sunucularında ölçeklenebilir ve güvenli uzaktan erişim geliştiriyor
  • Ağ bağlantılarını ve WireGuard tünellerini yönetmek için connlib adlı bir bağlantı kütüphanesi kullanıyor
  • Birçok yinelemenin ardından, hızlı ve kapsamlı testler, derin özelleştirme ve yüksek güvenilirlik sunan sans-IO adlı tasarıma ulaştı

connlib, Rust ile yazılmıştır ve sans-IO tasarımını izler

  • Rust'ın hızı ve bellek güvenliği sayesinde ağ hizmetleri geliştirmek için uygundur
  • tokio runtime'ı, tungstenite WebSockets, boringtun WireGuard implementasyonu, rustls ile API trafiği şifreleme gibi bileşenler kullanılır
  • sans-IO tasarımı, çeşitli yerlerde soketler üzerinden bayt gönderip almak yerine protokolü saf bir durum makinesi olarak uygular

Rust'ın asenkron modeli ve "function coloring" tartışması

  • Asenkron fonksiyonlar yalnızca diğer asenkron fonksiyonlardan çağrılabilir
  • Asenkron bir fonksiyonun derinliklerindeki bir fonksiyon, onu çağıran tüm fonksiyonların da asenkron hale gelmesini gerektirir
  • Bu durum, bağımlılıkların asenkron olup olmamasından bağımsız kod yazmak isteyenler için sorun yaratabilir

sans-IO'ya giriş

  • sans-IO'nun temel fikri, OOP dünyasındaki dependency inversion principle'a benzer
  • Politika (ne yapılacağı), implementasyon ayrıntılarına (nasıl yapılacağı) bağımlı olmamalıdır
  • Veriyi Transmit yapısını kullanarak göndermek yerine, Transmit üretir

Dependency inversion uygulaması

  • Veriyi Transmit yapısını kullanarak göndermek yerine, Transmit üretir
  • Event loop yan etkileri uygular ve gerçekten UdpSocket::send çağrısını yapar

Durum makinesi

  • STUN binding request durum makinesi diyagramı iki duruma sahiptir: Sent ve Received
  • Durum makinesini uygulamak için StunBinding yapısı ve ilgili fonksiyonlar tanımlanır

Event loop

  • Event loop, durum makinesini çalıştırır ve veriyi işlemek için poll_transmit ile handle_input kullanır

Zaman soyutlaması

  • Zaman tabanlı gereksinimleri işlemek için poll_timeout ve handle_timeout API'leri kullanılır

sans-IO'nun öncülü

  • sans-IO tasarımı, bağımlılıkların asenkron olup olmamasına dair kararı uygulamaya bırakır
  • sans-IO tasarımı kolay bileşir, esnek API'ler sunar, test etmeyi kolaylaştırır ve Rust'ın özellikleriyle iyi uyum sağlar

Kolay bileşim

  • StunBinding API'si çoğu ağ protokolüne uygulanabilir
  • Firezone'un snownet kütüphanesi, ICE ile WireGuard'ı birleştirerek ağ yapılandırmasından bağımsız çalışan "sihirli" bir IP tüneli sunar

Esnek API

  • Event loop'u doğrudan yazmak, kodu ayarlamayı mümkün kılar ve bakımı kolaylaştırır

Hızlı testler

  • sans-IO kodu yan etki içermediği için test edilmesi son derece kolaydır
  • Firezone, bir referans durum makinesi uygulayıp bunu connlib'in gerçek durumu ile karşılaştıran testler yürütür

Edge case'ler ve IO hataları

  • sans-IO tasarımı, protokol implementasyonunu gerçek IO yan etkilerinden ayırarak edge case'leri ve hata işlemeyi kolaylaştırır

Rust + sans-IO: Mükemmel eşleşme mi?

  • Rust, sahiplik ve değiştirilebilirliği açıkça modellediği için sans-IO tasarımıyla iyi uyum sağlar
  • sans-IO tasarımı, durum değişikliklerini ifade etmek için &mut'u serbestçe kullanır ve async Rust'tan farklı olarak yalnızca senkron API'ler kullanır

Dezavantajlar

  • Event loop'u doğrudan yazmak ince hatalara yol açabilir
  • Sıralı iş akışları daha fazla kod gerektirebilir
  • Rust topluluğunda sans-IO tasarımı hâlâ yaygın olarak kullanılmıyor

Sonuç

  • sans-IO kodu ilk başta alışılmadık gelebilir, ancak alışınca oldukça keyiflidir
  • Rust, durum makinelerini modellemek için mükemmel araçlar sunar
  • sans-IO tasarımı, hata işlemeyi girdi işlemenin bir parçası olmaya zorlayarak ağ kodu yazmanın doğru yolu gibi hissettirir

GN⁺ görüşü

  • sans-IO tasarımı, Rust'ın sahiplik modeliyle iyi uyuştuğu için ağ protokolü implementasyonları için çok uygundur
  • Event loop'u doğrudan yazmak, kodun esnekliğini artırır ve bakımını kolaylaştırır
  • Testlerin kolay olması, güvenilir kod yazmada büyük avantaj sağlar
  • Ancak Rust topluluğunda yaygın olmadığı için ilgili kütüphaneler yetersiz olabilir
  • Yeni bir teknoloji benimsenirken öğrenme eğrisi ve topluluk desteği de dikkate alınmalıdır

1 yorum

 
GN⁺ 2024-07-05
Hacker News görüşleri
  • Rust'a async/await sözdizimi gelmeden önce durum makineleri elle uygulanıyordu

    • Rust'ın async/await sözdizimi sayesinde üretkenlik büyük ölçüde arttı
    • Rust'ın async yapısı otomatik bir durum makinesine dönüştürülür ve I/O noktalarında değerleri saklar
  • VT100 kütüphanesi yazarken Rust'ın kapsülleme deseni sorununu fark etmiş

    • Kapsüllemeye aşırı takılmak sorun çıkarıyor
    • Bilgisayarların girdi alan, veriyi dönüştüren ve çıktı üreten makineler olduğunu hatırlatıyor
  • Veriyi aktarmak için channel kullanılan tasarımla karşılaştırma

    • Kod daha karmaşık hale geliyor
    • Mesaj türlerini elle uygulamak gerekiyor
    • Göndericiyi açıkça sağlamak gerekiyor
    • Ağ iletimi başarısız olursa sonuç alınamıyor
    • Ancak bazı kullanışlı yönleri de var
  • Haskell ekosisteminde mantık ile yürütmeyi ayırma fikri var

    • tokio::select! çağrısını nasıl kapsüllediklerinden bahsedilmiyor
    • sans-IO tarzında kapsüllenmiş bir fonksiyon uygulamasıyla ilgilenmiş
  • Rust'ın async fonksiyonları durum makinelerine derlenir

    • Sans-IO ile async'i birleştirmeye yönelik girişimler olup olmadığını merak ediyor
    • Temel sorun kullanılabilirlik ve Pin yönetimi
  • Durum açığa çıkarılırsa async fonksiyonlar "saf" hale gelebilir

    • OpenSSL'i async Rust'a bağlamaya çalışmış
  • Firezone etkileyici bir araç

    • Rust-libp2p'de benzer bir desen bulmuş
  • Derleyicinin async kodu otomatik olarak sans-IO'ya dönüştürebilmesi güzel olurdu

    • Elle dönüştürme hata üretmeye çok yatkın
  • Makale ve yorumları okuyunca, sanki hexagonal ya da ports/adapters mimari tarzını yeniden icat etmişler gibi görünüyor

  • Gerçek trafiğin gateway üzerinden mi geçtiğini, yoksa bunun yalnızca bağlantı kurulumunda mı kullanıldığını merak ediyor