5 puan yazan GN⁺ 2023-12-02 | 1 yorum | WhatsApp'ta paylaş
  • Karmaşık frontend uygulamaları, API yanıtı önbelleğinden başlayıp manuel indeksler ve önbellek geçersiz kılmaya kadar sorumluluk üstlenerek, her projede küçük bir veritabanını yeniden uygulamaya yakın bir duruma gelir
  • React gibi deklaratif framework’lerde her render’da API çağırmamak için yerel state veya Redux katmanında önbellek tutulur; bu katman giderek merkezi depo rolünü üstlenir
  • ID tabanlı depolama ve tarihe göre sorgulama yapıları sorguları hızlandırır, ancak CACHE ve ENTRIES_BY_DATE gibi birden fazla yapı arasında tutarlılığı korumak test ve kod inceleme yükü olarak büyür
  • İyimser değişiklikler, sunucu yanıtından önce UI’ı hemen güncelleyerek algılanan hızı artırır; ancak istemci-sunucu mantığının tekrarlanması, devam eden değişikliklerin izlenmesi, hata geri alma ve uygulama yeniden başlatıldıktan sonra uzlaştırma gibi tutarlılık maliyetlerini beraberinde getirir
  • SQLSync, SQLite tabanlı yerel veritabanı ve Git Rebase benzeri senkronizasyonla frontend stack’i içinde kalıcı önbellek, indeksler, kısıtlar, iyimser değişiklikler ve reaktif sorgular sunmayı amaçlar

Frontend önbelleğinin veritabanına dönüşme süreci

  • Frontend veri yönetimi, API yanıtlarını yerel değişkenlerde saklayan basit bir önbellek olarak başlayabilir
    • React gibi deklaratif framework’ler, kullanıcı etkileşimi sırasında ağacı birden çok kez yeniden render eder
    • Her render’da API isteği göndermemek için istek sonucu veya hata useState ve useEffect ile bileşen state’inde saklanabilir
    • Örnekler açıklık için basitleştirilmiştir; pratikte doğrulanmış API kütüphanelerini kullanma seçeneği de vardır
  • Önbellek, UI ağacında daha üst bir katmana veya UI’ın dışına taşınabilir
    • Redux, state’i birleştiren ve zaman içindeki atomik değişiklikleri koordine eden bir React state yönetimi kütüphanesidir
    • Redux ekosistemi, API verisi önbelleğe almayı yöneten araçlar ve desenlerle genişlemiştir
    • Bu kullanım biçiminin amacı önbellek mantığını merkezileştirmek, güncellemeleri koordine etmek ve önbellek sonuçlarını bileşenler arasında paylaşmaktır
  • Önbellekleme katmanı büyüdükçe, render motoruna ve kullanıcı aksiyonlarına uygun şekilde veriyi verimli ele alan merkezi bir depolama sistemine yaklaşır

Manuel indeksler ve tutarlılık yükü

  • Frontend’de de sunucudan alınan veriler, hızlı sorgulama ve güncelleme için ID’yi anahtar olarak kullanan nesnelerde saklanabilir
    • REST API kullanan uygulamalarda veriyi toplu okumak ve gerekli nesneleri ek bilgilerle zenginleştirmek sık görülür
    • Nesneleri ID’ye göre saklamak, API sonuçlarını önbellekle birleştirmeyi kolaylaştırır
    • Bu yapı ID’ye göre oluşturma, okuma, güncelleme ve silme için optimize edilmiştir
  • Birden çok öğeyi taramayı gerektiren filtreleme, tüm girdileri kontrol etmekten kaçınmak için ayrı bir indeks oluşturulmasına yol açar
    • createdAt değerinin yıl/ay/gün bölümlerini temel alan bir ENTRIES_BY_DATE yapısı oluşturulursa belirli bir tarihteki girdiler hızlı bulunabilir
    • Buna karşılık CACHE ile ENTRIES_BY_DATE arasındaki tutarlılığı sürekli korumak gerekir
    • Tarih aralığı sorguları birden fazla erişim gerektirir; tarihe göre sıralı dizi ve daha karmaşık sorgulama-güncelleme mantığı daha iyi bir yapı olabilir
  • İndeksler çoğaldıkça her indeks için oluşturma, güncelleme ve sorgulama mantığı gerekir
    • Doğruluğun denetlenmesi test ve kod inceleme yükü olarak büyür
    • Bir indekste silme veya güncelleme atlanırsa bulunması zor hatalar oluşabilir
    • Yeni uygulama özelliklerinden çok bu karmaşıklığı yöneten altyapıya daha fazla zaman harcanabilir
  • Gerçek veritabanı indeksleri, veriyi yalnızca başka bir biçimde saklamaktan çok daha karmaşıktır
    • İstatistik toplama, veri sürüm yönetimi, işlem kontrolü, kilitleme ve sorgu optimizasyonuyla etkileşim gibi unsurlar içerir

İyimser değişikliklerin eklediği tutarlılık sorunları

  • İyimser değişiklik, sunucu yanıtından önce belirli bir işlemin etkisini yerelde önceden simüle eder
    • UI, ağ gecikmesi yokmuş gibi anında tepki verebilir
    • Sunucu beklenenden farklı bir karar verirse veya hata oluşursa UI değişikliği geri alıp kullanıcıdan sorunu düzeltmesini isteyebilir
    • İstemci sunucu sonucunu iyi tahmin edebildiğinde, hatalar istemcide ele alınabildiğinde ve mantık sıkı şekilde senkronize olduğunda güçlü bir araç olur
  • İyimser güncelleme genelde dört aşamada ilerler
    • UI bir yazma işlemi üretir
    • Sunucunun kabul edeceği varsayımıyla yerel önbelleğe değişiklik uygulanır ve UI hemen yeniden render edilir
    • Değişiklik işlemi asenkron olarak sunucuya gönderilir
    • Sunucu yanıtı yerel önbellekle birleştirilerek önceki iyimser değişikliklerin üzerine yazılır ve gerekirse UI yeniden render edilir
  • Sunucuyla tutarlılığı korumak için çeşitli yükler ortaya çıkar
    • Sonucu tahmin etmek için istemci ve sunucuda mantığı tekrarlamak gerekir
    • Asenkron hataları veya sunucu uyumsuzluklarını ele almak için devam eden her değişikliği izlemek gerekir
    • Daha iyi kullanıcı deneyimi için iyimser önbellek bölümünü kalıcı hale getirip uygulama yeniden başlatıldıktan sonra değişiklikleri uzlaştırmak gerekebilir
  • Bu süreç geliştirme süresini ve doğruluk denetimi maliyetini artırır; veri yönetimi, kullanıcı değeri veya farklılaştırıcı özellik geliştirmesinin önüne geçebilir

Özyinelemeli önbellek geçersiz kılmanın karmaşıklığı

  • Çok veri içeren uygulamalarda aynı bilgi önbelleğin birden çok yerinde görünür
    • Örnek önbellek projects, tasks, users öğelerini birlikte saklar
    • Bir görev tamamlandıktan sonra proje ilerlemesi, kullanıcıya atanmış görevler ve yeni görev bilgisi gibi birden çok bölüm etkilenebilir
  • Görev tamamlandıktan sonra önbelleği sunucuyla eşleştirmek için birden çok gidiş-dönüş gerekebilir
    • Görevin tamamlandığını sunucuya bildir
    • Proje ilerlemesi değiştiği için projeyi yenile
    • Yeni görev ataması olup olmadığını kontrol et
    • Yeni atama varsa ilgili görevi sorgula
  • Daha karmaşık API’lerle gidiş-dönüş sayısı azaltılabilir; ancak API veya istemci mantığının temel veri modeliyle bağlanması sonucu kalır
    • GraphQL bu soruna yönelik bir yaklaşımdır, ancak tam bir çözüm değildir
  • UI’ın her değişiklikte önbelleğin hangi bölümünün ilgili olduğunu bilmesi gereken yapı, ölçek büyüdükçe kırılgan hale gelir
    • Veri ilişkileri ve agregasyonlar yerel önbelleğin birden çok bölümünü etkileyebilir
    • Mühendislik ekibi büyüdüğünde sorun ekip sınırlarını aşabilir ve büyük yazılım projelerindeki değiştirilebilir global değişkenlere benzer hissedilebilir
  • İyimser değişikliklerle birleştiğinde istemci, sunucu değişikliklerini tahmin etmek için daha fazla backend mantığını kopyalamaya başlar
    • Örnekte task 1’i user 1’den kaldırıp toplam görev sayısını kullanarak ilerlemeyi yeni orana göre hesaplamaya çalışabilir
    • İç içe geçmiş değişiklikleri yerelde tahmin edebilir hale getirdikçe istemci backend stack’ini daha fazla tekrarlar

SQLSync’in önerdiği frontend veritabanı stack’i

  • SQLSync, SQLite üzerine kurulmuş frontend için optimize edilmiş bir veritabanı stack’idir
    • Senkronizasyon motoru Git ve dağıtık sistem fikirlerini temel alır
    • React, Vue, Next.js gibi popüler frontend framework’leriyle sorunsuz entegre olacak şekilde tasarlanmıştır
    • Hedefi, zor veri yönetimi problemlerini ele alarak geliştiricilerin uygulamaya özgü özelliklere odaklanmasını sağlamaktır
  • Örnek Todo app, tüm veri katmanını 60 satır Rust ve bileşenlere dağılmış birkaç SQL sorgusuyla uygular
    • SQLSync; kalıcı önbellek, SQLite’ın indeks-kısıt-trigger-sorgu optimizasyonu özellikleri, iyimser değişiklikler, akıllı önbellek geçersiz kılma ve reaktif sorgular sağlar
  • Yerel veri bir veya daha fazla SQLite veritabanında saklanır
    • İndeksler kolayca oluşturulabilir ve veriyle otomatik senkronize olur
    • Veritabanı, backend’de olduğu gibi sorguları hızlandırmak için indeksleri otomatik kullanabilir
    • SQL karmaşık veri sorgularını ifade edebilir; triggers, foreign keys, constraints, full-text search gibi özellikler de kullanılabilir
  • İyimser değişiklikler reducer ile ele alınır
    • Yapı, Redux’un temel kavramlarına benzer
    • Reducer, WebAssembly’ye derlenebilen herhangi bir dille yazılabilir
    • SQLSync değişiklikleri istemcide iyimser olarak, sunucuda ise küresel olarak tutarlı bir sırada çalıştırır
    • Ardından istemci, Git Rebase benzeri bir işlemle sunucuyla senkronize olur
  • Bu mimarinin özyinelemeli önbellek geçersiz kılma ihtiyacını ortadan kaldırma avantajı vardır
    • Tüm veri değiştirme mantığı, istemci ve sunucu arasında paylaşılması kolay bir reducer içine yazılır
    • Değişiklik sırasında oluşan tüm veri değişimleri otomatik olarak görünür
    • Senkronizasyon Git Rebase gibi çalıştığından, sunucu istemciden farklı değişiklikler yapsa bile istemcinin aynı tutarlı sonuca ulaşacağı garanti edilir

İlgili çalışmalar

  • Riffle’ın “Building data-centric apps with a reactive relational database” yazısı, UI state’i dahil tüm uygulama state’ini tek bir reaktif veritabanında saklama fikrini ele alır
    • Reaktif sorgular temiz bir düşünme modeli sunar ve React gibi deklaratif sistemlerle iyi uyum sağlar
    • İstemci uygulama geliştirme problemlerini veritabanı topluluğunun fikirleriyle çözer
    • State’i ilişkisel veri modeli ve gerçek indekslerle modellemenin avantajlarını ele alır
  • Instant.db’den Stepan, tarayıcı içindeki veritabanını ele alan iki yazı yazdı
    • Database in the Browser, a Spec
    • A Graph-Based Firebase
    • İki yazı da frontend ve backend stack’lerinin ilişkisine daha fazla odaklanarak benzer problemleri ele alır ve Instant.db’nin Firebase’in grafik tabanlı ardılı olarak oluşturulma motivasyonunu açıklar
  • Matt Wonlaw’un CR-SQLite projesi bir SQLite uzantısıdır
    • Veriyi tutarlı şekilde birleştirmek için çakışmasız çoğaltılmış veri tipleri (CRDT) ve nedensel sıralı olay günlüğü kullanır
    • Merkezi bir koordinatör olmadan peer-to-peer uygulamaların SQLite’ta veri saklamasını ve işbirliği yapmasını sağlar
    • Tarayıcıda SQLite çalıştırmanın bir örneğidir
  • Matt Wonlaw ilgili fikirleri de araştırıyor

1 yorum

 
GN⁺ 2023-12-02
Hacker News görüşleri
  • Bu projeyi iyi biliyorum ve yapan kişi arkadaşım, o yüzden buraya gelip soruları yanıtlamasını sağlayacağım
    Kendisi deneyimli bir veritabanı mimarı. SQLsync'i, frontend geliştiricilerinin uzak veritabanını sanki tamamen tarayıcının içindeymiş gibi sorgulayıp güncelleyebilmesi için yaptı. Aslında neredeyse öyle ve WASM sayesinde tüm SQLite veritabanı tarayıcıya gönderilebiliyor. Kilit nokta, birden fazla istemci arasında senkronizasyon sağlayan akıllıca ama basit bir reaktif algoritma
    Geliştirme işinin önemli bir kısmının veri senkronizasyonu olduğunu düşünürsek, React ve REST API de bir tür senkronizasyon prosedürü olarak görülebilir ve bu yaklaşım yeni olasılıklar açıyor. API'den çekilip önbelleğe alınmış nesne ağaçlarıyla garip özel yapım bir veritabanı daha kurmak yerine, ilişkisel veritabanının gücüyle yerelde doğrudan güncelleme ve sorgulama yapılabilir

    • Tüm sorgu sistemini frontend'e taşımak, birçok frontend geliştiricisinin gerçekten istediği şey gibi görünüyor. İnsanlar veri üzerinde güçlü bir sorgu sistemi istiyor; aktarım katmanını, REST'i, GraphQL'i ya da *RPC gibi şeyleri durmadan yeniden icat etmek istemiyor
      Ancak geleneksel web şirketlerinde, uzmanlaşmış backend/frontend ekipleri yüzünden bunu benimsemek zor. Veritabanı, backend, aktarım ve kimlik doğrulama katmanlarını çıkarıp bunları tek blokluk bir sistemle değiştirmek anlamına geliyor ve sistem mimarlarının çoğu backend kökenli olduğu için bu sorunu iyi anlamıyor. Her iki tarafa da derinden dokunduğu için mevcut sistemlere pek uymuyor; sonuçta daha çok yeni geliştirmeler için uygun. Backend ne AWS ya da Azure hizmeti ne de Lambda dostu, bu yüzden karşılaştığım mimar tiplerinin çoğu buna el atmak istemeyecektir
      Bu yaklaşımın bir kısmı aslında eski bir teknoloji olan CouchDB+PouchDB ile zaten vardı. Bazı kullanım alanlarına oldukça iyi uyuyor, ama sorgu sistemi ideal değil ve kimlik doğrulama ile veri kapsamı belirleme biçimi çoğu kişiye yabancı geliyor. Veri tamamen tek bir kullanıcıya ait olduğunda ve kullanıcı başına veritabanı modelini aynen kullandığınızda en kolay senaryo ortaya çıkıyor. Veriyi CRDT ile güçlü biçimde bölümlerseniz çatışma sorunu da büyük ölçüde azalıyor
      Ama ölçeklenebilirlik sorunları var. CouchDB'de 10 bin ila 100 bin kullanıcı bağlandığında CPU gereksinimi çok yükseliyor; teknoloji eski olsa da hâlâ bakımı yapılıyor. Sistem tasarımı açısından, kullanıcılar arasında veri paylaşımına başladığınız anda karmaşıklık hızla artıyor; bu da karmaşıklığı çözmekten çok yerini değiştirmek anlamına geldiği için uygunluğu düşürüyor
      Bu yaklaşım da aynı hedefi gözetiyor gibi, ama benzer ölçeklenebilirlik sorunları yaşaması kuvvetle muhtemel. Nasıl gelişeceğini merak ediyorum; bir ilk adım gibi görünüyor
    • Bu, uzaktan senkronize edilen ve ardından eşler arasında yeniden senkronize edilen bir veritabanını sorgulayıp güncelleyebildiğiniz Couchbase'e oldukça benziyor gibi geliyor. Sunucu tarafı JavaScript eklentileriyle kimlik doğrulama veya iş mantığı da kolayca kontrol edilebiliyor
    • Yalnızca ilgili kısımları LocalStorage / SessionStorage içinde önbelleğe almak neden yeterli olmuyor, gerçekten merak ediyorum
      Chrome'un zamanında tarayıcıya kelimenin tam anlamıyla bir SQL veritabanı koymaya çalıştığını hatırlıyorum, ama işler pek yolunda gitmedi ve localStorage ana akım oldu. Bunun faydasını küçümsemek için söylemiyorum; genelde tarayıcının sunduğunu seçme eğilimindeyim. WASM ve onun daha da olgunlaşması ya da yeteneklerinin artmasıyla, bunu tarayıcıya taşıma ihtimali beni epey heyecanlandırıyor
  • Eskiden çalıştığım bir şirket, değişiklik işlemleri için check-out/check-in mekanizmasına sahip proje yönetim yazılımı kullanıyordu. Projeyi check-out ettiğinizde yerelde düzenleyebileceğiniz bir kopya indiriliyor, check-in yaptığınızda ise tekrar sunucuya yükleniyordu. Check-out durumunda proje kilitleniyordu. Canlı güncellemeli uygulamalar çağında bunun herkes için eski bir yöntem olduğu hissi vardı
    Ama 10 yıl boyunca SPA web uygulamaları yaptıktan sonra, o veri senkronizasyon yönteminin zamanının ötesinde olduğu hissine kapıldım

    • Birden fazla kullanıcının paralel canlı güncellemesini destekleyip desteklemeyeceğiniz ya da aynı anda yalnızca tek bir güncellemeye izin verecek şekilde kilitleyip kilitlemeyeceğiniz, sonuçta teknik değil iş kararıdır. Asıl mesele, uygulamaya uygun iş kurallarının eşzamanlı canlı güncellemeleri ele almanıza izin verip vermediğidir
      Sonunda mesele, birden fazla eşzamanlı güncelleme arasındaki tutarsızlıkları tutarlı biçimde çözebilecek bir prosedür uygulayıp uygulayamayacağınıza dayanır. Bunun mümkün olduğu durumlar da vardır, olmadığı durumlar da; bu teknik beceriden çok iş kurallarına bağlıdır
      Eğer iş kuralları gereği bir çözüm mekanizması uygulanamıyorsa, eşzamanlı güncellemeleri destekleyecek teknik kapasiteniz olsa bile aynı anda yalnızca tek bir güncellemeye izin verecek kilitleme gerekir
    • Bu yola giderseniz birçok sorun çözülür ve uygulaması da çok kolay olur
      Ama insanları gerçekten istedikleri şeyin bu olduğuna ikna etmek zordur. Her şeyin her zaman erişilebilir olması gerektiği gibi büyük bir yanılsamaya kapılmak kolay, ama gerçekte genellikle bir seferde bir kişi değişiklik yapar; iki ya da daha fazla kişi birlikte çalışacaksa zaten çoğu zaman konuşup iletişim kurarak uzlaşmaları gerekir
      Git gibi tamamen dağıtık geliştirmede bile çatışmaları sihirli şekilde otomatik çözemezsiniz. Doğru değişikliği seçmek için yine de başkalarıyla iletişim kurmanız ve bağlamı anlamanız gerekir
    • İnsanlar MySQL gibi klasik ilişkisel veritabanı paradigmasını NoSQL ya da MongoDB gibi ilişkisel olmayan veritabanlarına kıyasla küçümsese bile, tam da bu yüzden hâlâ ayakta kalıyor. Sırf daha hızlı ya da daha havalı diye her şeyin yerini alamazsınız
      Bazı şeyler kanıtlanmış çözümler gerektirir
    • RCS gibi geliyor https://en.wikipedia.org/wiki/Revision_Control_System
      Şirketin zamanında RCS'den CVS'ye geçtiğinde, ekip arkadaşlarımdan birinin CVS'nin kilitlemeli check-out'u desteklememesine sinirlendiğini hatırlıyorum
      https://en.wikipedia.org/wiki/Concurrent_Versions_System
    • Bu yaklaşımı seviyorum. SQLSync aslında bunu sürekli yapıyor sayılır, ama açıkça koordine edilirse böyle bir check-in/check-out yöntemi de mümkün olabilir
      Tek sahipli kilitleme stratejisinin de SQLSync ile simüle edilebileceğini düşünüyorum. Yine de uygulamaya göre buna ihtiyaç olmayabilir. Amaç çevrimdışı çalışma yapıp hazır olduğunuzda birleştirmekse, SQLSync bu kalıbı zaten yerleşik olarak sunuyor. Amaç yalnızca tek bir istemcinin değişiklik yapabilmesini sağlamaksa, merkezi kilitleme kalıbı gerekir ve bunun da SQLSync üzerinden koordine edilmesi mümkün olabilir
  • Burada “ölçülen şey yönetilir” ilkesi ile batık maliyet safsatası iç içe geçiyor.
    Veritabanlarının asıl sorunu karmaşıklık. Tek tek her özellik genelde güvenli olsa da, güvenilirlik, önbellekleme ve indeksler birbirine girdiği anda karmaşıklık patlıyor ve çoğu durumda alanına özgü bir DB uygulamak mantıklı olmuyor.
    Ama şirketin bu üç özelliği uygulamaya zaten yatırım yaptığını ve buna çok kaynak gömdüğünü fark ettiğiniz noktada, politik olarak bunu kaldıralım demeyi önermek zorlaşıyor; teknik borcu tek seferde temizlemenin gerçek maliyeti de yüksek oluyor.
    Asıl sorunun SQL sözdizimi olduğunu düşünüyorum. Temel ilişkisel veritabanlarını kullanma deneyimi bozuk İngilizce yerine aşina olunan C benzeri sözdizimi kadar rahat olsaydı, insanlar kendileri bir şeyler yazmak yerine DB kullanmaya daha çok yönelirdi. NoSQL veritabanları bu yönde iyi bir adımdı ama çoğu, gündelik kullanışlılıktan çok büyük veriye aşırı odaklandı. Redis gibi şeyler ise yerini buldu ve gayet iyi.
    SQL’i çalıştırmayı kolaylaştırmak makul bir yaklaşım, ancak sevdiğim Postgres gibi iyi veritabanlarında temel dil SQL olduğu için, o dili kullanmadan verim almak zor. Postgres’i eksiksiz kopyalayan ama varsayılan ayrıştırıcısı daha iyi sözdizimine sahip bir dili destekleyen PostgresPostSQL gibi bir veritabanına gerçekten ihtiyaç var

    • SQL’de tam olarak neyin zor olduğunu bilmiyorum. Bence her geliştirici SQL bilmeli. SQL sözdizimi de iyi ve bu kadar uzun süre ayakta kalacak kadar kendini kanıtladı. Onu suçlamak yerine gerçekten öğrenmeye zaman ayırmak daha faydalı olur
    • SQL sık sık eleştiriliyor ve bence bunun geçerli nedenleri de var, ama neden daha iyisini yapamadık?
      Genel programlamada onlarca dil kullanılıyor ve bunlar sürekli evriliyor. Tarayıcının çalıştırdığı ve kullanıcı tarayıcısını kontrol edemediğimiz için değiştirmesi zor olan JavaScript bile transpiler’lar ve WebAssembly sayesinde evriliyor.
      Ama veritabanlarında fiilen sadece SQL var. Alternatifler var ama kullanım açısından SQL’e yaklaşan yok. Belki de SQL o kadar kötü değildir.
      Bunun nedeni ilişkisel modelin gerçekten çok iyi olması olabilir. Bunun dışına çıkma girişimlerinin ancak niş alanlarda tutma ihtimali yüksek. Bildirimsel tarz da çok iyi; bundan uzaklaşarak büyük başarı elde etmek de zor. Sonunda sadece sözdizimi farklı bir SQL yapacaksanız, çoğu insan için bu, yaklaşımı değiştirecek kadar büyük bir iyileştirme olmayacaktır
    • Keşke Postgres’te SQL’den daha kararlı ve daha düşük seviyeli bir API olsaydı. Bu, EXPLAIN ile elde edilen sorgu planına benzer bir biçimde olabilir
      Bu API hedeflenerek yazılan uygulamalar bir SQL DB uygulayabilir. SQL’i ayrıştırıp bu API’ye uyan sorgu planları üreten bir sorgu planlayıcısı yazmak yeterli olur
    • SQL’den doğrudan kaçınmak isteyenler için, veritabanının üstüne bir anlam katmanı ekleme yaklaşımına bakıp bakmadığını merak ediyorum
  • Yazar burada. Soruların çoğuna ancak göz gezdirebildim; kaçırdığım bir şey var mı diye düzenli olarak kontrol etmeye devam edeceğim. HN tartışmalarını daha iyi takip etmenin bir yolunu birinin yapıp yapmadığını da merak ediyorum.
    Şimdiye kadarki tartışma çok sevindirici. İlk yazı, SQLSync’in tam olarak nasıl çalıştığından çok, benim SQLSync’i yapmama yol açan frontend mühendisliği motivasyonuna odaklanmıştı. Nasıl çalıştığını bir sonraki yazıda ele alacağım

    • Mobil desteği planlıyor musunuz merak ediyorum. Bunu en çok denemek istediğim yer tam olarak mobil tarafı
  • Kullanıcılara, gerçekliğin sert biçimde ya da görünmez şekilde bozabileceği bir zihinsel model vermemelisiniz.
    İstemci-sunucu modeli yerine veritabanını senkronize etme yaklaşımının böyle bir durum olmasından endişe ediyorum. Senkronizasyon mekanizması dümdüz çökebilir ya da karşılanmayan derin varsayımlar olabilir.
    Hızlı bir UI gerekiyorsa, CRDT ilkel öğelerinden oluşan bir küme kurup kullanmak bana daha güvenli geliyor; geri kalan her şeyi de form gönderimi olarak bırakırdım

    • Katılıyorum. SQLSync kullanan geliştiricilerin zihinsel modeli kolayca kavrayabilmesini sağlamak hedeflerden biri. Önyargılı olabilirim ama kişisel olarak rebase modeli bana CRDT’den çok daha anlaşılır geliyor
  • İstemci ile sunucu arasındaki durum senkronizasyonu lanetli bir problem.
    Biraz kullanıcı deneyimi fedakârlığını kabul edip PHP / sunucu tarafı render modeline daha yakın bir yaklaşıma dönerseniz, bu problemi bütünüyle bertaraf edebilirsiniz. SPA güzel ama multipart form gönderimi de hâlâ çalışıyor. Çok az miktarda JavaScript ile kalan pürüzlerin büyük kısmı da giderilebilir.
    Son dönem web ürünlerinde istemci tarafı durum, üçüncü taraf IdP’nin kimlik doğrulama claim’leri, sorgu parametrelerindeki birinci taraf oturum kimliği ve mevcut dokümandan ibaret. Birincisinin nerede tutulduğunu dürüst olmak gerekirse ben de bilmiyorum. O Microsoft’un problemi, bizim değil. Geri kalan tüm durum sunucuda.
    İstemciyi bütün gün sadece girdi basan aptal bir terminal gibi ele alıyoruz. Birinci taraf çerezler ya da local storage da kullanmıyoruz. Bu yaklaşım, iOS/Safari için geliştirme deneyimini büyük ölçüde iyileştirdi.
    Bu yüzden aslında sunmak istediğiniz deneyimin ne olduğunu ve bunun neden istemci ile sunucu durumunu ayırmayı haklı çıkaracak kadar güçlü olduğunu sormak istiyorum

    • Tüketiciye dönük grafik arayüzlerde iyimser render çok yaygın bir akış ve bunu yapıyorsanız istemci/sunucu durumuyla uğraşıyorsunuz demektir. Hâlâ orada burada yükleme spinner’ları görüyoruz ama bunlar genelde ilk içerik yüklemesi için. Örneğin Gmail, bir e-postayı arşivlerken sizi bekletmiyor
    • ElectricSQL bu sorunu çözme yolunda büyük ilerleme kaydetti. İstemcide SQLite’a yazıp Postgres ile senkronizasyonu garanti ediyor.
      Referans: https://news.ycombinator.com/item?id=37584049
  • SQLite tabanlı offline/local-first yaklaşım son zamanlarda epey popüler görünüyor. Bu hafta bununla ilgili okuduğum üçüncü yazı ve umut verici duruyor.
    Ama ElectricSQLhttps://electric-sql.com/ ve PowerSynchttps://powersync.com/ ile karşılaştırınca nasıl?

    • Gerçekten de çok sıcak bir alan. Farklı yaklaşımların ortaya çıktığını görmek çok ilginç.
      ElectricSQL ve PowerSync’in ikisi de kısmi replikasyon gibi çok zor bir problemi ele alıyor. Amaçları, geleneksel merkezi veritabanının istemcinin ihtiyaç duyduğu kısmı yalnızca istemciye çift yönlü senkronize ederken, iyimser değişiklikleri ve buna bağlı tutarlılık/çatışma yönetimini de destekleyen genel bir çözüm üretmek.
      Dezavantajı ise uygulama karmaşıklığı. Değişiklikleri yalnızca o alt kümeye itebilmek için her istemcinin tüm veritabanının hangi alt kümesine sahip olduğunu doğru biçimde takip etmek gerekiyor. Ayrıca veritabanı durumunun hangi alt kümesinin indirileceğini belirtmek için yeni bir DSL gerekiyor; bunu da ayrıca öğrenmek ve optimize etmek lazım. Yine de bu kadar zor bir problemi çözüyor olmaları sevindirici ve SQLSync kısmi replikasyonu desteklemeye hazır olduğunda ortada zaten yerleşmiş en iyi uygulamalar olacaktır.
      Buna karşılık SQLSync şu anda yalnızca tüm DB senkronizasyonu destekliyor. Tüm istemciler tüm veritabanı için tutarlı bir görünüm görüyor. Bunun iyi bir fikir olup olmadığı hemen sorgulanabilir ve bazı uygulamalar için uygun değil. Ama kişisel finans uygulamasını düşünürseniz, temel hedef cihazlar arası senkronizasyon, bulut yedeği, offline çalışabilme gibi şeylerse tüm DB’nin her cihaza kaydedilmesi aslında istenen yaklaşım olabilir. Airtable benzeri doküman odaklı veri modeli de bir örnek olabilir. Her Airtable’ı ayrı bir veritabanı olarak tutarsanız, hangi tablolarla ilgilenileceğini istemci yönetebilir.
      Tüm DB senkronizasyonuna odaklanınca, senkronizasyon motoru kısmi replikasyonu destekleyen çözümlere göre çok daha basit hale geliyor. Bunun avantajlarından biri de backend’in çok hafif olması. Şu anki demo(https://sqlsync-todo.pages.dev) Cloudflare Durable Objects içinde çok az depolama ve CPU süresi kullanarak tamamen çalışıyor.
      SQLSync’in bu kullanım senaryolarını mümkün kılması için yapılacak daha çok şey var ve hâlâ bir prototipe yakın, ama ilk testler oldukça olumluydu.
  • Büyük multi-tenant uygulamalarda, tek tek veri kümeleri nispeten küçük olduğunda birkaç kez “veritabanını doğrudan istemciye göndersek nasıl olur” diye düşündüm. Yeterince standart dışı ve lanetli bir mimari desen gibi göründüğü için çok ileri gitmedim. Yanıldığımı öğrenmek isterim.

    • Bunu bir kalori takip uygulamasında bir kez yaptım. Veritabanında yüz binlerce gıda olsa da uygulama çoğu medya uygulaması veya oyundan çok daha az yer kaplıyordu.
    • Ben de bunun lanetli bir yaklaşım olup olmadığını merak ediyorum. Şimdiye kadar beklediğimden çok daha iyi gitti. https://sqlsync-todo.pages.dev gibi uygulamalar bu desenle önemsiz hale geliyor.
      Bunu gerçekten kanıtlamak için yapılacak çok iş var ama nereye varacağını görmek için devam etmeyi gerçekten heyecan verici buluyorum.
    • Doğru cevap, UI’ı veritabanının zaten bulunduğu sunucuya geri taşımak ve istemci tarafındaki HTML renderer’a, yani web tarayıcısına, yalnızca HTML göndermek. Bu yazının tamamı daha çok “frontend çizgiyi aştı, uçurumu geçti ve denize düştü” gibi.
  • Bu, SPA’den vazgeçildiğinde tamamen ortadan kalkan problemlerden biri gibi görünüyor.
    Hotwire veya htmx tarzı çözümler kullanırsanız, sorgu sadece sunucu sorgusu olur ve bu sorguları hızlı hale getirme problemi çok daha iyi anlaşılmıştır.

    • Bu yalnızca web sitelerinin problemi değil. Mobil ve masaüstü ekosistemleri de tarayıcılar gibi büyük ölçüde thin client yönüne mi kaymalı? Apple Reminders veya Google Tasks gibi basit uygulamalar gecikme ya da bağlantı sorunları yüzünden GUI’yi kilitlemek zorunda mı kalmalı?
    • Yakın zamanda htmx denedim; ortadan kaldırdığı karmaşıklık ve bunun sonucundaki üretkenlik artışı gerçekten inanılmaz. İstediğiniz stack’i aynen kullanabilmeniz de büyük nimet.
      Bunu ocaml + web components ile kullandım ve üretkenlik 10/10 deneyimiydi. Sadece göz kırpmaktan hızlı derlenen bir build tool yeterli oluyor ve frontend ile backend arasında JSON eşleme kablolaması da gerekmiyor; bu yüzden gerçekten çok üretken.
    • Açıkçası Hotwire veya Livewire gibi çözümler SPA kadar anlık hissettirmiyor.
      Ben şahsen InertiaJs https://inertiajs.com tercih ediyorum. Sunucuyla durumu “eski usul” senkronize eden bir tür frontend router sistemi.
    • Bu, “çok etkileşimli web uygulamaları yapmayın” ya da “birden fazla VM gerektiren servisler işletmeyin” demeye benziyor. Saçma bir görüş.
    • Bence sorun, SPA’den uzaklaşınca değil; kullanılabilir ürünlerin sıkça sahip olduğu yüksek etkileşimli özelliklerden uzaklaşınca ortadan kalkıyor.
      Özellikle de internetin kararsız olduğu bölgelerde çalışması gereken bir ürünse bu daha da geçerli.
  • Şu anda tam da “full-stack veritabanı” hakkında çok benzer bir yazı yazıyorum. Birçok uygulamanın backend ve veritabanı mantığını frontend istemci kodunda yeniden kurduğu kalıbı ele alıyor. Bizim önerdiğimiz çözüm, hem sunucuda hem istemcide çalışabilen bir veritabanı seçip ikisi arasını senkronize etmek
    Ürünümüzde SQLite kullanmamamızın nedeni, dürüst olmak gerekirse SQL'in uygulama verisini sorgulamak için doğru araç olmaması. İstemci kodunda istenen veri yapısıyla kolayca örtüşmüyor ve neredeyse hiçbir SQL veritabanında, sorguyu tekrar tekrar poll etmek yerine sorgu değişikliklerine abone olmanın bir yolu yok
    İstemcide tam bir veritabanı bulundurma fikri hoşunuza gidiyor ve TypeScript/JavaScript ile derin entegrasyon istiyorsanız, geliştirdiğimiz https://github.com/aspen-cloud/triplit projesine göz atabilirsiniz

    • Aslında Postgres, WAL üzerinden gerçek zamanlı değişiklik aboneliği için harika bir yöntem sunuyor. Bu açık kaynak kütüphanenin bakımını da ben yapıyorum
      https://github.com/cpursley/walex
    • SQLite aslında update hook aracılığıyla değişiklikleri tespit etmek için gereken mekanizmayı sağlıyor. Birçok SQLite binding'inin bunu dışa açmaması üzücü
      Ben bunu oldukça basit kullanıyorum. Temel tablolardaki veri değiştiğinde sorguyu otomatik olarak yeniden çalıştırıyorum. Sonuçları kademeli olarak güncellemek kadar verimli olmayabilir ama SQLite sorguları genelde o kadar hızlı ki bunun büyük bir sorun olduğunu düşünmüyorum
    • İstemci kodunda istenen veri yapısıyla kolayca örtüşmediği görüşüne katılmıyorum. Veri normalizasyonu, frontend reaktif uygulamaları için önemli ve veriyi güncel tutmak için fiilen gerekli. Tüm CRUD işlemleri de çok daha kolay yönetiliyor
    • Realm Sync ve Mongo + Kotlin Multiplatform ile sunucu, web, mobil, masaüstü gibi neredeyse tüm platformları kapsayabilirsiniz. Elbette bir maliyeti var. Alternatiflerle gerçekten ilgileniyorum; bunun yazıya dahil olup olmayacağını da merak ediyorum