אחסון עם ביצועים גבוהים לאפליקציה: Storage Foundation API

פלטפורמת האינטרנט מציעה יותר ויותר למפתחים את הכלים הדרושים להם כדי ליצור אפליקציות עם ביצועים גבוהים ומשופרים לאינטרנט. הגורם המשמעותי ביותר הוא ש-WebAssembly (Wasm) פתח את הגישה לאפליקציות אינטרנט מהירות ועוצמתיות, ואילו טכנולוגיות כמו Emscripten מאפשרות עכשיו למפתחים להשתמש שוב בקוד שכבר נבדק באינטרנט. כדי לנצל את הפוטנציאל הזה באמת, המפתחים צריכים ליהנות מאותם העוצמה והגמישות של האחסון.

כאן נכנסים לתמונה Storage Foundation API. Storage Fundamentals API הוא ממשק API חדש לאחסון נתונים מהירים וללא תכנות, שמאפשר לכם לחשוף תרחישי שימוש חדשים ומבוקשים באינטרנט, כמו הטמעה של מסדי נתונים בעלי ביצועים טובים וניהול אלגנטי של קבצים זמניים גדולים. בעזרת הממשק החדש הזה, המפתחים יכולים "לקנות לעצמם אחסון" לאינטרנט, וכך לצמצם את הפער בין התכונות בקוד באינטרנט לבין קוד ספציפי לפלטפורמה.

ה-Storage Foundation API תוכנן כך שידמה מערכת קבצים בסיסית מאוד, ומעניק למפתחים גמישות באמצעות יצירת רכיבים בסיסיים, פשוטים ובעלי ביצועים גבוהים, שבאמצעותם הם יכולים ליצור רכיבים ברמה גבוהה יותר. אפליקציות יכולות לנצל את הכלי שהכי מתאים לצרכים שלהן, ולמצוא את האיזון הנכון בין נוחות השימוש, הביצועים והאמינות.

למה האינטרנט זקוק לממשק API נוסף לאחסון?

פלטפורמת האינטרנט מציעה כמה אפשרויות אחסון למפתחים, כשכל אחת מהן בנויה בהתאם לתרחישים לדוגמה ספציפיים.

  • חלק מהאפשרויות האלה לא חופפות להצעה, כי הן מאפשרות אחסון של כמויות קטנות מאוד של נתונים, כמו קובצי cookie או Web Storage API שכולל את המנגנונים sessionStorage ו-localStorage.
  • אפשרויות אחרות כבר הוצאו משימוש מסיבות שונות, כמו File and Directory credentials API או WebSQL.
  • ל-File System Access API יש פלטפורמת API דומה, אבל הוא משמש ממשק עם מערכת הקבצים של הלקוח ומתן גישה לנתונים שעשויים להיות מחוץ למקור או אפילו לבעלות של הדפדפן. ההתמקדות השונה הזו כרוכה בשיקולי אבטחה מחמירים יותר, ובעלויות ביצועים גבוהות יותר.
  • אפשר להשתמש ב-IndexedDB API כקצה עורפי לחלק מתרחישי השימוש של Storage Foundation API. לדוגמה, Emscripten כולל את IDBFS, מערכת קבצים קבועה שמבוססת על IndexedDB. עם זאת, מכיוון ש-IndexedDB הוא מאגר של ערכי מפתח, יש לו מגבלות ביצועים משמעותיות. בנוסף, ב-IndexedDB קשה עוד יותר לגשת ישירות לחלקי משנה של קובץ.
  • לבסוף, ממשק CacheStorage נתמך בצורה רחבה ומכוון לאחסון נתונים בגודל גדול כמו משאבים של אפליקציות אינטרנט, אבל הערכים לא ניתנים לשינוי.

Storage Foundation API הוא ניסיון לסגור את כל הפערים באפשרויות האחסון הקודמות, על ידי מתן הרשאה לאחסון ביצועים של קבצים גדולים שניתנים לשינוי שהוגדרו במקור האפליקציה.

הצעות לתרחישים לדוגמה ל-Storage Foundation API

דוגמאות לאתרים שבהם אפשר להשתמש ב-API הזה:

  • אפליקציות לפרודוקטיביות או ליצירתיות שפועלות על כמויות גדולות של נתוני וידאו, אודיו או תמונה. אפליקציות כאלה יכולות להוריד עומסים של קטעים לדיסק במקום לשמור אותם בזיכרון.
  • אפליקציות שמסתמכות על מערכת קבצים קבועה שנגישה מ-Wasm וצריכות ביצועים טובים יותר ממה שמבטיחים ב-IDBFS.

מה זה Storage Foundation API?

ה-API כולל שני חלקים עיקריים:

  • קריאות למערכת קבצים, שמספקות פונקציונליות בסיסית לאינטראקציה עם קבצים ונתיבי קבצים.
  • כינויים לקבצים, שמספקים גישת קריאה וכתיבה בקובץ קיים.

קריאות למערכת קבצים

ב-Storage Foundation API מוצג אובייקט חדש, storageFoundation, שנמצא באובייקט window וכולל כמה פונקציות:

  • storageFoundation.open(name): פותח את הקובץ עם השם הנתון אם הוא קיים ויוצר קובץ חדש בדרך אחרת. מחזירה הבטחה שמסתיימת עם הקובץ הפתוח.
  • storageFoundation.delete(name): הסרת הקובץ עם השם הנתון. מחזירה הבטחה עם תאריך מחיקה של הקובץ.
  • storageFoundation.rename(oldName, newName): שינוי השם של הקובץ מהשם הישן לשם החדש באופן אטומי. מחזירה הבטחה שמסתיימת כשמשנים את שם הקובץ.
  • storageFoundation.getAll(): מחזירה הבטחה שמסתיימת במערך של כל שמות הקבצים הקיימים.
  • storageFoundation.requestCapacity(requestedCapacity): מבקשת קיבולת חדשה (בבייטים) לשימוש לפי ההקשר הנוכחי של הביצוע. הפונקציה מחזירה ערך שטופל עם כמות הקיבולת שנותרה.
  • storageFoundation.releaseCapacity(toBeReleasedCapacity): משחרר את מספר הבייטים שצוין מהקשר הביצוע הנוכחי, ומחזיר הבטחה שמסתיימת בקיבולת הנותרת.
  • storageFoundation.getRemainingCapacity(): מחזירה הבטחה שמסתיימת בקיבולת שזמינה להקשר הביצוע הנוכחי.

כינויים לקבצים

העבודה עם קבצים מתבצעת באמצעות הפונקציות הבאות:

  • NativeIOFile.close(): סוגר קובץ ומחזיר הבטחה שמסתיימת כשהפעולה מסתיימת.
  • NativeIOFile.flush(): מסנכרן (כלומר, מנקה) את מצב הזיכרון של קובץ עם התקן האחסון, ומחזיר הבטחה שמסתיימת בסיום הפעולה.
  • NativeIOFile.getLength(): מחזירה הבטחה שמסתיימת בהתאם לאורך הקובץ בבייטים.
  • NativeIOFile.setLength(length): מגדיר את אורך הקובץ בבייטים ומחזיר הבטחה שתפוג בסיום הפעולה. אם האורך החדש קטן מהאורך הנוכחי, הבייטים יוסרו החל מסוף הקובץ. אחרת הקובץ מורחב עם בייטים בעלי ערך אפס.
  • NativeIOFile.read(buffer, offset): קריאת תוכן הקובץ בהיסט הנתון באמצעות מאגר נתונים זמני שנוצר מהעברת מאגר הנתונים הזמני, שלאחר מכן נותק ממנו. הפונקציה מחזירה את הערך NativeIOReadResult עם המאגר הזמני שהועבר ומספר הבייטים שנקראו בהצלחה.

    NativeIOReadResult הוא אובייקט שמורכב משתי רשומות:

    • buffer: ArrayBufferView, שהוא התוצאה של העברת מאגר הנתונים הזמני אל read(). הוא מאותו הסוג והאורך של מאגר הנתונים הזמני של המקור.
    • readBytes: מספר הבייטים שנקראו בהצלחה לתוך buffer. יכול להיות שהגודל של מאגר הנתונים הזמני יהיה קטן יותר ממאגר הנתונים הזמני, אם יש שגיאה או שטווח הקריאה נמשך מעבר לסוף הקובץ. הערך מוגדר לאפס אם טווח הקריאה נמצא מעבר לסוף הקובץ.
  • NativeIOFile.write(buffer, offset): כתיבת התוכן של מאגר הנתונים הזמני בתוך הקובץ בקיזוז הנתון. מאגר הנתונים הזמני מועבר לפני כתיבה של נתונים כלשהם, ולכן הוא נשאר מנותק. הפונקציה מחזירה NativeIOWriteResult עם מאגר הנתונים הזמני שהועבר ומספר הבייטים שנכתבו בהצלחה. הקובץ יורחב אם טווח הכתיבה יחרוג מהאורך שלו.

    NativeIOWriteResult הוא אובייקט שמורכב משתי רשומות:

    • buffer: הערך ArrayBufferView, שהוא התוצאה של העברת מאגר הנתונים הזמני אל write(). הוא מאותו הסוג והאורך של מאגר הנתונים הזמני של המקור.
    • writtenBytes: מספר הבייטים שנכתבו בהצלחה אל buffer. במקרה של שגיאה, יכול להיות שהגודל הזה יהיה קטן יותר ממאגר הנתונים הזמני.

דוגמאות מלאות

כדי להבהיר את העקרונות שלמעלה, הנה שתי דוגמאות שלמות שמסבירות את השלבים השונים במחזור החיים של קובצי Storage Foundation.

פתיחה, כתיבה, קריאה, סגירה

// 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();
}

פתיחה, רישום, מחיקה

// 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();

הדגמה (דמו)

אפשר לשחק עם הדגמה של Storage Foundation API בהטמעה שמופיעה בהמשך. יוצרים קבצים, משנים את השם שלהם, כותבים בהם וקוראים אותם, ורואים את הקיבולת הזמינה שביקשתם לעדכן במהלך ביצוע השינויים. אפשר למצוא את קוד המקור של ההדגמה ב-Glitch.

אבטחה והרשאות

צוות Chromium תכנן והטמיע את Storage Foundation API באמצעות עקרונות הליבה שהוגדרו בשליטה בגישה לתכונות מתקדמות של פלטפורמת אינטרנט, כולל בקרת משתמשים, שקיפות וארגונומיה.

בהתאם לדפוס הזה של ממשקי API מודרניים אחרים לאחסון באינטרנט, הגישה ל-Storage Foundation API קשורה למקור, כלומר מקור יכול לגשת רק לנתונים שנוצרו בעצמו. הוא מוגבל גם להקשרים מאובטחים.

שליטת משתמשים

מכסת האחסון תשמש לחלוקת גישה לשטח הדיסק ולמניעת ניצול לרעה. קודם צריך לבקש את הזיכרון שרוצים לשמור. בדומה לממשקי API אחרים לאחסון, המשתמשים יכולים לפנות את השטח שהוקצה על ידי Storage Foundation API דרך הדפדפן שלהם.

קישורים שימושיים

אישורים

ממשק Storage Foundation API צוין והוט על ידי עמנואל קריבוי וריצ'רד סטוץ. המאמר הזה נבדק על ידי Pete LePage ו-Joe Medley.

התמונה הראשית (Hero) דרך Markus Spiske במשחק Un לשמור.