- Local-first uygulamalar, hızlı tepki süresi ve varsayılan gizlilik vaat eder; ancak pratikte çevrimdışı desteği uygulamak son derece zordur.
- Bunun en büyük nedeni senkronizasyonun karmaşıklığıdır; birden fazla cihazda veri aynı anda değiştirildiğinde sonuçta tam olarak aynı duruma yakınsaması gerekir.
- Burada iki büyük teknik zorluk vardır:
- zaman sırasının belirsizliği
- çakışmalar
- Bu sorunu çözmek için Hybrid Logical Clocks(HLCs) ve CRDTs gibi dağıtık sistem tasarımlarının uygulanması gerekir.
- SQLite tabanlı genişletmeler kullanılarak güvenilir ve basit bir senkronizasyon mimarisi sunulabilir ve bu mimari tüm platformlarda kullanılabilir.
Çevrimdışı-first uygulamaların vaadi ve gerçeği
- Çevrimdışı-first uygulamalar; anında tepki, varsayılan gizlilik ve istikrarsız ağ koşullarında bile yükleme beklemeden kullanım vaat eder.
- Gerçekte ise çoğu uygulama çevrimdışı desteğini düzgün biçimde uygulayamaz; büyük kısmı yalnızca değişiklikleri yerelde geçici olarak saklayıp ağ bağlantısı geldiğinde göndermeyi tercih eder.
- Bu tür uygulamalar güvenilir değildir ve sonunda "değişiklikler kaydedilmeyebilir" gibi uyarı mesajlarına yol açar.
Senkronizasyonun temel zorluğu
- Bir local-first uygulama geliştirirken kaçınılmaz olarak bir dağıtık sistem kurmuş olursunuz.
- Birden fazla cihaz çevrimdışıyken birbirinden bağımsız olarak veriyi değiştirebilir ve daha sonra yeniden bağlandıklarında aynı duruma doğru biçimde yakınsamaları gerekir.
- Bunun için iki büyük zorluk vardır:
- olayların sırasındaki belirsizlik
- aynı veri üzerindeki çakışmalar
1. Olay sırasının belirsizliği
- Birden fazla cihazda olaylar farklı zamanlarda gerçekleşir ve sıraya bağlı olarak durum değişebilir.
- Örnek: A cihazı
x=3 olarak ayarlar, B cihazı x=5 olarak ayarlar → her biri çevrimdışıyken değişiklik yaparsa, senkronizasyon sırasında farklı sonuçlar ortaya çıkabilir.
- Geleneksel merkezi veritabanları bunu güçlü tutarlılık ile çözer; ancak bu, küresel senkronizasyon gerektirdiği için local-first sistemlere uygun değildir.
- Sonuç olarak her olay için uygun sıranın, dinamik ve dağıtık bir ortamda da kesinleştirilmesi gerekir; bunu merkezi bir saat olmadan yapmanın bir yolu gereklidir.
Hybrid Logical Clocks(HLCs) kullanımı
- Hybrid Logical Clocks(HLCs), ayrı cihazlar arasında olay sırası üzerinde fiilen uzlaşmayı sağlayan basit ama etkili bir algoritmadır.
- HLC, fiziksel zaman bilgisi ile mantıksal sayacı birleştirerek çalışır.
- Örneğin:
- A cihazı bir olayı 10:00:00.100 anında kaydederse HLC değeri
(10:00:00.100, 0) olur.
- Mesajı alan B cihazının saati geri kalsa bile HLC değerini
(10:00:00.100, 1) seviyesine çıkarır.
- Böylece iki cihazın fiziksel saatleri arasındaki farktan bağımsız olarak olayların doğru sırası belirlenebilir.
2. Çakışma sorunu
- Doğru sırayı uygulamak tek başına yeterli değildir; farklı cihazlar aynı veriyi bağımsız biçimde değiştirdiğinde çakışmalar kaçınılmaz olarak ortaya çıkar.
- Çoğu sistem geliştiricinin çakışma çözüm kodunu elle yazmasını ister; bu da hata riskini ve bakım yükünü artırır.
CRDTs kullanımı
- En iyi yaklaşım Conflict-Free Replicated Data Types(CRDTs) kullanmaktır.
- CRDTs, senkronizasyon hangi sırayla yapılırsa yapılsın ya da aynı işlem tekrar uygulanırsa uygulansın, her cihazın durumunun sonunda aynı olmasını garanti eder.
- En basit CRDT stratejisi Last-Write-Wins(LWW) yaklaşımıdır.
- Her güncellemeye bir zaman damgası verilir.
- Senkronizasyon sırasında daha yeni zaman damgasına sahip değer seçilir.
SQLite'ın avantajları
- Bir local-first uygulama kurarken güvenilir ve hafif bir yerel veritabanı zorunludur ve SQLite en iyi seçimdir.
- SQLite tabanlı framework genişletmeleriyle senkronizasyon işlevi uygulanırsa şu avantajlar elde edilir:
- Mesaj uygulama süreci basittir: mevcut değeri oku → yeni zaman damgası daha yeniyse üzerine yaz → değilse yok say.
- Bu yöntem, senkronizasyon sırasından bağımsız olarak tüm cihazlarda durumun yakınsamasını garanti eder.
Mimarinin önemi
- Bu yapı basit ve güvenilir senkronizasyonu mümkün kılar.
- Haftalar boyunca çevrimdışı kalınsa bile veri kaybı olmadan güvenilirlik
- Her zaman nihai duruma yakınsayan deterministik yapı
- Ağır bağımlılıklar olmadan yalnızca hafif bir SQLite genişletmesi ile çözüm
- iOS, Android, macOS, Windows, Linux, WASM gibi tüm büyük platformların desteği
Geliştiricilere öneri
- Basit bir istek kuyruğuyla çevrimdışı modu sadece 'taklit eden' yaklaşımdan kaçınmak gerekir.
- Eventual consistency kavramını benimseyip HLC ve CRDT gibi kanıtlanmış dağıtık sistem tekniklerinden yararlanmak gerekir.
- Büyük ve karmaşık framework'ler yerine küçük ve bağımlılıksız yapılar tercih edilmelidir.
- Sonuçta uygulamalar anında çalışma, çevrimdışı kullanım, varsayılan gizlilik gibi avantajlardan yararlanabilir.
Açık kaynak SQLite-Sync notu
- Üretimde hemen kullanılabilecek, çapraz platform bir çevrimdışı-first motorla ilgileniyorsanız açık kaynak SQLite-Sync genişletmesine göz atabilirsiniz.
1 yorum
Hacker News görüşleri
dirtyolarak işaretleyip eşzamansız kaydetme işleminin başarıyla tamamlanmasını beklemek yeterli. Çevrimdışı uygulama tasarımında büyük değişiklikler gerekmiyor; sadece daha iyi alışkanlıklar olsa sorunların çoğu kolayca çözülebilirCache-Controldoğru kullanılıp ağ katmanında buna uyulunca pek çok sorun çözülüyor. Böylece sunucuda önbellek süresi değişse bile uygulamayı güncellemeden bu hemen uygulanabiliyor