restate / v1.0.0
น่าเชื่อถือตั้งแต่การออกแบบ
restate รับประกันอะไรเมื่อที่จัดเก็บข้อมูลช้า ล้มเหลว หรือไม่มี และวิธีอ่านข้อผิดพลาดที่มันรายงาน
ในหน้านี้
การรับประกันบันทึกตามลำดับลองดูเมื่อการโหลดล้มเหลวบันทึกแล้วปิดที่จัดเก็บข้อมูลใช้ไม่ได้การตรวจสอบและย้ายรูปแบบข้อมูลที่บันทึกไว้ที่จัดเก็บข้อมูลของคุณเองขีดจำกัดและการหมดเวลารหัสข้อผิดพลาดการรับประกัน
พฤติกรรมนี้เป็นส่วนหนึ่งของสัญญา 1.0 และครอบคลุมโดยการทดสอบของแพ็กเกจ
| สถานการณ์ | สิ่งที่ restate ทำ |
|---|---|
บันทึกหลายครั้งติดกัน | ทำตามลำดับทีละ store การบันทึกที่รอคิวจะเขียนค่าล่าสุด |
โหลดระเบียนไม่สำเร็จ | autoSave และการบันทึกแบบกลุ่มข้ามมันไปพร้อม LOAD_FAILED มีเพียง save() ที่เรียกโดยตรงที่แทนที่ได้ |
คอมโพเนนต์ unmount ระหว่างบันทึก | การบันทึกที่ขอไว้จะเสร็จ การเขียนหลังจากนั้นลงใน store ที่ถูกทำลายจะถูกเพิกเฉย |
ที่จัดเก็บข้อมูลใช้ไม่ได้ | store ทำงานในหน่วยความจำ status().available เป็น false และการบันทึกถูกปฏิเสธ |
อะแดปเตอร์ค้าง | การทำงานหมดเวลาหลัง operationTimeoutMs และงานถัดไปจะรอให้อะแดปเตอร์ทำเสร็จ |
งานค้างมากเกินไป | การทำงานใหม่ถูกปฏิเสธด้วย QUEUE_FULL แทนที่จะเพิ่มขึ้นไม่สิ้นสุด |
บันทึกตามลำดับ
การทำงานของ store หนึ่งไม่เคยซ้อนทับกัน การบันทึกที่เริ่มขณะอีกงานรออยู่จะใช้ค่าล่าสุด การบันทึกทุกครั้งที่เปลี่ยนจึงเขียนสถานะสุดท้ายได้โดยไม่ทำให้คิวเต็ม
useDraft.set('A');
const first = useDraft.save(); // writes "A"
useDraft.set('B');
const second = useDraft.save(); // waits in the queue
useDraft.set('C');
const third = useDraft.save(); // joins the waiting save
await Promise.all([first, second, third]); // ['A', 'C', 'C'] — two writesลองดู
ทำให้ที่จัดเก็บข้อมูลช้าลง ทำให้การเขียนล้มเหลว หรือเอาที่จัดเก็บข้อมูลออกไปเลย
กำลังเตรียมตัวอย่าง…
เมื่อการโหลดล้มเหลว
restateManager.ready ถูกปฏิเสธด้วย BULK_OPERATION_FAILED และแสดงรายการทุก store ที่ล้มเหลว จนกว่าระเบียนนั้นจะโหลดได้ autoSave และ saveAll จะไม่แทนที่มันและรายงาน LOAD_FAILED
ลองใหม่ด้วย initialize() เพื่อเก็บการเปลี่ยนแปลงไว้แล้วบันทึก เรียก restore() เพื่อทิ้ง หรือ save() เพื่อเขียนทับระเบียนโดยตั้งใจ
try {
await restateManager.ready;
} catch (error) {
// BULK_OPERATION_FAILED: one entry per store that could not load.
for (const { store, error: cause } of error.failures) {
console.error(store.key, cause.code);
}
}บันทึกแล้วปิด
การบันทึกที่ขอไว้ก่อน unmount ยังทำจนเสร็จ ตัวจัดการ "บันทึกแล้วปิด" จึงไม่ต้องรอ
function Document({ onClose }) {
const useDraft = useRestateScope((scope) => persistedRestate('', { scope, key: 'draft' }));
const saveAndClose = () => {
useDraft.save(); // finishes even after this component unmounts
onClose();
};
// …
}การตรวจสอบและย้ายรูปแบบข้อมูลที่บันทึกไว้
version, migrate และ validate ปกป้องคุณจากระเบียนเก่าหรือเสียหาย validate ทำงานก่อนบันทึกและหลังกู้คืนหรือย้ายรูปแบบ
import { persistedRestate } from '@kkwaenggwari/restate';
const useSettings = persistedRestate(
{ theme: 'system' },
{
key: 'settings',
version: 2,
migrate(value, from, to) {
if (from === 1 && to === 2 && typeof value?.darkMode === 'boolean') {
return { theme: value.darkMode ? 'dark' : 'light' };
}
throw new Error('Unsupported stored version');
},
validate: (value) => ['system', 'light', 'dark'].includes(value?.theme),
},
);ที่จัดเก็บข้อมูลของคุณเอง
ออบเจกต์ใดที่มี getItem, setItem และ removeItem ใช้ได้ทั้งหมด เมธอดคืนค่าหรือ Promise ก็ได้ ส่วน isAvailable เป็นตัวเลือก
import { persistedRestate } from '@kkwaenggwari/restate';
const sessionStorageAdapter = {
isAvailable: () => typeof sessionStorage !== 'undefined',
getItem: (key) => sessionStorage.getItem(key),
setItem: (key, value) => sessionStorage.setItem(key, value),
removeItem: (key) => sessionStorage.removeItem(key),
};
export const useFilters = persistedRestate(
{ query: '' },
{
key: 'filters',
storage: sessionStorageAdapter,
},
);ขีดจำกัดและการหมดเวลา
กำหนดว่าการทำงานหนึ่งใช้เวลาได้นานเท่าไร รอได้กี่งาน และค่าใหญ่ได้แค่ไหน
persistedRestate(value, {
key: 'draft',
operationTimeoutMs: 10_000, // default 30000
maxPendingOperations: 64, // default 256
maxStorageCharacters: 1_000_000,
});รหัสข้อผิดพลาด
ข้อผิดพลาดที่ restate สร้างมี name เป็น RestateError มี code และสำหรับ store แบบบันทึกมี key อะแดปเตอร์ที่จัดเก็บข้อมูลและ callback ของคุณปฏิเสธด้วยข้อผิดพลาดของตัวเองได้
| รหัส | ความหมาย |
|---|---|
BULK_OPERATION_FAILED | การเรียกแบบกลุ่มอย่าง restateManager.ready หรือ saveAll มีความล้มเหลว ดู error.failures |
INDEXEDDB_ABORTED | ทรานแซกชัน IndexedDB ถูกยกเลิก |
INDEXEDDB_BLOCKED | การเปิดฐานข้อมูลถูกบล็อกโดยการเชื่อมต่อในแท็บอื่น |
INDEXEDDB_CONNECTION_CLOSING | การเชื่อมต่อฐานข้อมูลกำลังปิดตอนที่คำขอเริ่ม |
INDEXEDDB_OPEN_FAILED | เปิดฐานข้อมูลไม่ได้ |
INDEXEDDB_REQUEST_FAILED | คำขอ IndexedDB ล้มเหลว |
INDEXEDDB_STORE_MISSING | ฐานข้อมูลที่มีอยู่แล้วขาด object store |
INVALID_STORAGE_RECORD | ระเบียนที่บันทึกไว้ไม่ใช่ระเบียน restate ที่ถูกต้อง |
INVALID_STORED_VALUE | ค่าไม่ผ่าน validate |
LIFECYCLE_LIMIT | updater เริ่มและหยุดซ้ำไปมา |
LOAD_FAILED | โหลดระเบียนไม่ได้ การบันทึกอัตโนมัติหรือแบบกลุ่มจึงไม่แทนที่มัน |
MMKV_UNAVAILABLE | โหลด react-native-mmkv ไม่ได้ |
MULTIPLE_ERRORS | callback หลายตัวล้มเหลวในการทำงานเดียว ดู error.errors |
NOTIFICATION_LIMIT | observer คอยตั้งเวลาการเปลี่ยนแปลงวนไม่จบ |
OBSERVER_ERROR | listener หรือ callback ของวงจรชีวิตโยนข้อผิดพลาด |
OPERATION_ABORTED | การทำงานกับที่จัดเก็บข้อมูลถูกยกเลิก |
QUEUE_FULL | มีงานรออยู่มากกว่าที่ maxPendingOperations อนุญาต |
REENTRANT_SETTER | updater ของ state พยายามเปลี่ยน store เดียวกันขณะที่ตัวเองกำลังทำงาน |
SCOPE_DESTROYED | มีการใช้ scope ที่ถูกทำลายแล้วเพื่อสร้าง store |
SEQUENCE_EXHAUSTED | ลำดับภายในใช้ตัวระบุจนหมด |
STORAGE_BLOCKED | การเรียกอะแดปเตอร์ครั้งก่อนยังไม่จบหลังหมดเวลาหรือถูกยกเลิก |
STORAGE_TIMEOUT | การทำงานใช้เวลานานกว่า operationTimeoutMs |
STORAGE_UNAVAILABLE | ใช้ที่จัดเก็บข้อมูลที่นี่ไม่ได้ store ยังทำงานในหน่วยความจำต่อไป |
STORAGE_VALUE_TOO_LARGE | ค่าที่เข้ารหัสแล้วเกิน maxStorageCharacters |
STORAGE_VERSION_MISMATCH | ระเบียนมีเวอร์ชันต่างออกไปและไม่มีฟังก์ชัน migrate ใดรองรับ |
STORE_DESTROYED | มีการสมัครรับ store ที่ถูกทำลายแล้ว หรือขอให้มันใช้ที่จัดเก็บข้อมูล |