Uygulamanız için yüksek performanslı depolama: Storage Foundation API

Web platformu, geliştiricilere web için ince ayarlı yüksek performanslı uygulamalar oluşturmak üzere ihtiyaç duydukları araçları giderek daha fazla sunmaktadır. En önemlisi, WebAssembly (Wasm) hızlı ve güçlü web uygulamalarının önünü açarken Emscripten gibi teknolojiler artık geliştiricilerin denenmiş ve test edilmiş kodları web'de yeniden kullanmasına olanak tanıyor. Geliştiricilerin bu potansiyelden tam olarak yararlanabilmesi için depolama konusunda aynı güce ve esnekliğe sahip olması gerekir.

Bu noktada Storage Foundation API devreye girer. Storage Foundation API, web için yeni ve çok istenen kullanım alanlarının (ör. yüksek performanslı veritabanları uygulama ve büyük geçici dosyaları sorunsuz bir şekilde yönetme) kilidini açan yeni, hızlı ve tarafsız bir depolama API'sidir. Bu yeni arayüz sayesinde geliştiriciler, web'e "kendi depolama alanlarını getirebilir" ve web ile platforma özel kod arasındaki özellik farkını azaltabilir.

Storage Foundation API, çok temel bir dosya sistemine benzeyecek şekilde tasarlanmıştır. Bu nedenle, geliştiricilere daha üst düzey bileşenler oluşturabilecekleri genel, basit ve etkili temel öğeler sağlayarak esneklik sunar. Uygulamalar, ihtiyaçlarına en uygun araçtan yararlanabilir, kullanılabilirlik, performans ve güvenilirlik arasında doğru dengeyi bulabilir.

Web'in neden başka bir depolama API'sine ihtiyacı var?

Web platformu, geliştiriciler için çeşitli depolama seçenekleri sunar. Bu seçeneklerin her biri belirli kullanım alanları göz önünde bulundurularak oluşturulmuştur.

  • Bu seçeneklerden bazıları, yalnızca çok küçük miktarda verinin depolanmasına izin verdiği için bu öneriyle açıkça çakışmıyor. Örneğin, çerezler veya sessionStorage ve localStorage mekanizmalarından oluşan Web Storage API.
  • Diğer seçenekler, File and Directory Entries API veya WebSQL gibi çeşitli nedenlerle kullanımdan kaldırılmıştır.
  • File System Access API'nin API yüzeyi benzerdir ancak bu API, istemcinin dosya sistemiyle arayüz oluşturmak ve kaynağın veya hatta tarayıcının sahipliği dışında olabilecek verilere erişim sağlamak için kullanılır. Bu farklı odak, daha katı güvenlik hususları ve daha yüksek performans maliyetleri ile birlikte gelir.
  • IndexedDB API, Storage Foundation API'nin bazı kullanım alanları için arka uç olarak kullanılabilir. Örneğin, Emscripten, IndexedDB tabanlı kalıcı bir dosya sistemi olan IDBFS'yi içerir. Ancak IndexedDB temel olarak bir anahtar-değer deposu olduğundan önemli performans sınırlamaları vardır. Ayrıca, IndexedDB'de bir dosyanın alt bölümlerine doğrudan erişmek daha da zor ve yavaştır.
  • Son olarak, CacheStorage arayüzü yaygın olarak desteklenir ve web uygulaması kaynakları gibi büyük boyutlu verilerin depolanması için ayarlanmıştır ancak değerler sabittir.

Storage Foundation API, uygulamanın kaynağında tanımlanan değiştirilebilir büyük dosyaların performanslı bir şekilde depolanmasına olanak tanıyarak önceki depolama seçeneklerindeki tüm boşlukları kapatmaya yönelik bir girişimdir.

Storage Foundation API için önerilen kullanım alanları

Bu API'yi kullanabilecek sitelere örnek olarak şunlar verilebilir:

  • Büyük miktarda video, ses veya resim verisiyle çalışan üretkenlik ya da yaratıcılık uygulamaları Bu tür uygulamalar, segmentleri bellekte tutmak yerine diske boşaltabilir.
  • Wasm'den erişilebilen kalıcı bir dosya sistemine dayanan ve IDBFS'nin garanti edebileceğinden daha fazla performansa ihtiyaç duyan uygulamalar.

Storage Foundation API nedir?

API'nin iki ana bölümü vardır:

  • Dosyalar ve dosya yollarıyla etkileşim kurmak için temel işlevler sağlayan dosya sistemi çağrıları.
  • Mevcut bir dosyaya okuma ve yazma erişimi sağlayan dosya tutamaçları.

Dosya sistemi çağrıları

Storage Foundation API, storageFoundation adlı yeni bir nesne sunar. Bu nesne, window nesnesinde bulunur ve çeşitli işlevler içerir:

  • storageFoundation.open(name): Belirtilen ada sahip dosya varsa bu dosyayı açar, yoksa yeni bir dosya oluşturur. Açılan dosya ile çözümlenen bir söz döndürür.
  • storageFoundation.delete(name): Belirtilen ada sahip dosyayı kaldırır. Dosya silindiğinde çözümlenen bir söz döndürür.
  • storageFoundation.rename(oldName, newName): Dosyayı eski adından yeni adına atomik olarak yeniden adlandırır. Dosya yeniden adlandırıldığında çözümlenen bir söz döndürür.
  • storageFoundation.getAll(): Mevcut tüm dosya adlarının dizisiyle çözümlenen bir söz döndürür.
  • storageFoundation.requestCapacity(requestedCapacity): Mevcut yürütme bağlamı tarafından kullanılmak üzere yeni kapasite (bayt cinsinden) ister. Kalan kapasite miktarıyla çözümlenen bir söz döndürür.
  • storageFoundation.releaseCapacity(toBeReleasedCapacity): Geçerli yürütme bağlamından belirtilen bayt sayısını serbest bırakır ve kalan kapasiteyle çözümlenen bir söz döndürür.
  • storageFoundation.getRemainingCapacity(): Geçerli yürütme bağlamı için kullanılabilir kapasiteyle çözümlenen bir söz döndürür.

Dosya tutmaçları

Dosyalarla çalışma aşağıdaki işlevler aracılığıyla gerçekleşir:

  • NativeIOFile.close(): Bir dosyayı kapatır ve işlem tamamlandığında çözümlenen bir söz döndürür.
  • NativeIOFile.flush(): Bir dosyanın bellekteki durumunu depolama cihazıyla senkronize eder (yani boşaltır) ve işlem tamamlandığında çözümlenen bir söz döndürür.
  • NativeIOFile.getLength(): Dosyanın bayt cinsinden uzunluğuyla çözülen bir söz döndürür.
  • NativeIOFile.setLength(length): Dosyanın uzunluğunu bayt cinsinden ayarlar ve işlem tamamlandığında çözümlenen bir söz döndürür. Yeni uzunluk, mevcut uzunluktan küçükse dosyanın sonundan başlayarak baytlar kaldırılır. Aksi takdirde, dosya sıfır değerli baytlarla genişletilir.
  • NativeIOFile.read(buffer, offset): Belirtilen arabelleğin aktarılmasıyla elde edilen ve daha sonra ayrılan arabellek aracılığıyla, belirtilen ofsetteki dosyanın içeriğini okur. Aktarılan arabellek ve başarıyla okunan bayt sayısını içeren bir NativeIOReadResult döndürür.

    NativeIOReadResult, iki girişten oluşan bir nesnedir:

    • buffer: ArrayBufferView, bu, read()'ye aktarılan arabelleğin sonucudur. Kaynak arabellekle aynı türde ve uzunluktadır.
    • readBytes: buffer'ye başarıyla okunan bayt sayısı. Bir hata oluşursa veya okuma aralığı dosyanın sonunu aşarsa bu değer arabellek boyutundan daha küçük olabilir. Okuma aralığı dosyanın sonunu aşıyorsa sıfır olarak ayarlanır.
  • NativeIOFile.write(buffer, offset): Belirtilen arabelleğin içeriğini, belirtilen uzaklıkta dosyaya yazar. Arabellek, herhangi bir veri yazılmadan önce aktarılır ve bu nedenle ayrılmış olarak bırakılır. Aktarılan arabellek ve başarıyla yazılan bayt sayısını içeren bir NativeIOWriteResult döndürür. Yazma aralığı uzunluğu aşarsa dosya uzatılır.

    NativeIOWriteResult, iki girişten oluşan bir nesnedir:

    • buffer: ArrayBufferView write()'e aktarılan arabelleğin aktarılması sonucu elde edilen. Kaynak arabellekle aynı türde ve uzunluktadır.
    • writtenBytes: buffer'ye başarıyla yazılan bayt sayısı. Hata oluşursa bu değer arabellek boyutundan daha küçük olabilir.

Eksiksiz örnekler

Yukarıda bahsedilen kavramları daha net bir şekilde açıklamak için, Storage Foundation dosyalarının yaşam döngüsündeki farklı aşamaları adım adım gösteren iki eksiksiz örnek aşağıda verilmiştir.

Açma, yazma, okuma, kapatma

// Open a file (creating it if needed).
const file = await storageFoundation.open('test_file');
try {
  // Request 100 bytes of capacity for this context.
  await storageFoundation.requestCapacity(100);

  const writeBuffer = new Uint8Array([64, 65, 66]);
  // Write the buffer at offset 0. After this operation, `result.buffer`
  // contains the transferred buffer and `result.writtenBytes` is 3,
  // the number of bytes written. `writeBuffer` is left detached.
  let result = await file.write(writeBuffer, 0);

  const readBuffer = new Uint8Array(3);
  // Read at offset 1. `result.buffer` contains the transferred buffer,
  // `result.readBytes` is 2, the number of bytes read. `readBuffer` is left
  // detached.
  result = await file.read(readBuffer, 1);
  // `Uint8Array(3) [65, 66, 0]`
  console.log(result.buffer);
} finally {
  file.close();
}

Açma, listeleme, silme

// Open three different files (creating them if needed).
await storageFoundation.open('sunrise');
await storageFoundation.open('noon');
await storageFoundation.open('sunset');
// List all existing files.
// `["sunset", "sunrise", "noon"]`
await storageFoundation.getAll();
// Delete one of the three files.
await storageFoundation.delete('noon');
// List all remaining existing files.
// `["sunrise", "noon"]`
await storageFoundation.getAll();

Güvenlik ve izinler

Chromium ekibi, kullanıcı kontrolü, şeffaflık ve ergonomi gibi Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme'de tanımlanan temel ilkeleri kullanarak Storage Foundation API'yi tasarladı ve uyguladı.

Web'deki diğer modern depolama API'leriyle aynı şekilde, Storage Foundation API'ye erişim kaynakla sınırlıdır. Yani bir kaynak yalnızca kendi oluşturduğu verilere erişebilir. Ayrıca, güvenli bağlamlarla da sınırlıdır.

Kullanıcı denetimi

Depolama alanı kotası, disk alanına erişimi dağıtmak ve kötüye kullanımı önlemek için kullanılır. Kullanmak istediğiniz bellek önce istenmelidir. Diğer depolama API'leri gibi, kullanıcılar da Storage Foundation API'nin kullandığı alanı tarayıcıları üzerinden temizleyebilir.

Faydalı bağlantılar

Teşekkür

Storage Foundation API, Emanuel Krivoy ve Richard Stotz tarafından belirtilmiş ve uygulanmıştır. Bu makale Pete LePage ve Joe Medley tarafından incelenmiştir.

Markus Spiske tarafından Unsplash'te yayınlanan hero resmi.