restate / v1.0.0
Tin cậy từ thiết kế
restate bảo đảm điều gì khi bộ nhớ lưu trữ chậm, thất bại hoặc không có, và cách đọc các lỗi nó báo.
Trên trang này
Bảo đảmLưu tuần tựThử ngayKhi tải thất bạiLưu và đóngBộ nhớ lưu trữ không khả dụngKiểm tra hợp lệ và di chuyển dữ liệu đã lưuBộ nhớ lưu trữ riêngGiới hạn và thời gian chờMã lỗiBảo đảm
Hành vi này là một phần của hợp đồng 1.0 và được test của gói bao phủ.
| Tình huống | restate làm gì |
|---|---|
Nhiều lần lưu liên tiếp | Chạy tuần tự theo từng store; lần lưu đang xếp hàng ghi giá trị mới nhất. |
Bản ghi không tải được | autoSave và lưu hàng loạt bỏ qua nó với LOAD_FAILED; chỉ save() tường minh mới thay thế nó. |
Component unmount trong lúc lưu | Lần lưu được yêu cầu vẫn hoàn tất; những lần ghi sau đó vào store đã hủy bị bỏ qua. |
Bộ nhớ lưu trữ không khả dụng | Store chạy trong bộ nhớ, status().available là false và việc lưu bị từ chối. |
Adapter bị treo | Thao tác hết thời gian sau operationTimeoutMs, và công việc sau đó chờ adapter hoàn tất. |
Quá nhiều việc đang chờ | Thao tác mới bị từ chối với QUEUE_FULL thay vì tăng lên không giới hạn. |
Lưu tuần tự
Các thao tác của một store không bao giờ chồng lên nhau. Lần lưu bắt đầu khi lần khác đang chờ sẽ lấy giá trị mới nhất, nên lưu ở mỗi thay đổi vẫn ghi trạng thái cuối mà không làm đầy hàng đợi.
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 writesThử ngay
Làm chậm bộ nhớ lưu trữ, khiến việc ghi thất bại hoặc bỏ hẳn bộ nhớ lưu trữ.
Đang chuẩn bị ví dụ…
Khi tải thất bại
restateManager.ready bị từ chối với BULK_OPERATION_FAILED và liệt kê mọi store bị lỗi. Cho đến khi bản ghi đó được tải, autoSave và saveAll không thay thế nó và báo LOAD_FAILED.
Thử lại bằng initialize() để giữ thay đổi rồi lưu chúng, gọi restore() để bỏ chúng, hoặc save() để cố ý ghi đè bản ghi.
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);
}
}Lưu và đóng
Lần lưu được yêu cầu trước khi unmount vẫn hoàn tất, nên handler "Lưu và đóng" không cần chờ.
function Document({ onClose }) {
const useDraft = useRestateScope((scope) => persistedRestate('', { scope, key: 'draft' }));
const saveAndClose = () => {
useDraft.save(); // finishes even after this component unmounts
onClose();
};
// …
}Kiểm tra hợp lệ và di chuyển dữ liệu đã lưu
version, migrate và validate bảo vệ bạn khỏi bản ghi cũ hoặc hỏng. validate chạy trước khi lưu và sau khi khôi phục hoặc di chuyển.
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),
},
);Bộ nhớ lưu trữ riêng
Bất kỳ đối tượng nào có getItem, setItem và removeItem đều dùng được. Các phương thức có thể trả về giá trị hoặc Promise; isAvailable là tùy chọn.
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,
},
);Giới hạn và thời gian chờ
Đặt thời gian tối đa cho một thao tác, số lượng được phép chờ và độ lớn tối đa của một giá trị.
persistedRestate(value, {
key: 'draft',
operationTimeoutMs: 10_000, // default 30000
maxPendingOperations: 64, // default 256
maxStorageCharacters: 1_000_000,
});Mã lỗi
Lỗi do restate tạo có name là RestateError, có code, và với store được lưu có key. Adapter lưu trữ và callback của bạn có thể từ chối bằng lỗi riêng.
| Mã | Ý nghĩa |
|---|---|
BULK_OPERATION_FAILED | Một lời gọi hàng loạt như restateManager.ready hoặc saveAll gặp lỗi; xem error.failures. |
INDEXEDDB_ABORTED | Giao dịch IndexedDB bị hủy. |
INDEXEDDB_BLOCKED | Việc mở cơ sở dữ liệu bị một kết nối ở tab khác chặn. |
INDEXEDDB_CONNECTION_CLOSING | Kết nối cơ sở dữ liệu đang đóng khi yêu cầu bắt đầu. |
INDEXEDDB_OPEN_FAILED | Không mở được cơ sở dữ liệu. |
INDEXEDDB_REQUEST_FAILED | Yêu cầu IndexedDB thất bại. |
INDEXEDDB_STORE_MISSING | Cơ sở dữ liệu đã tồn tại nhưng thiếu object store. |
INVALID_STORAGE_RECORD | Bản ghi đã lưu không phải bản ghi restate hợp lệ. |
INVALID_STORED_VALUE | Giá trị không qua được validate. |
LIFECYCLE_LIMIT | Updater liên tục bắt đầu rồi dừng. |
LOAD_FAILED | Bản ghi không tải được, nên việc lưu tự động hoặc hàng loạt không thay thế nó. |
MMKV_UNAVAILABLE | Không tải được react-native-mmkv. |
MULTIPLE_ERRORS | Nhiều callback thất bại trong một thao tác; xem error.errors. |
NOTIFICATION_LIMIT | Các observer liên tục lên lịch thay đổi trong một vòng lặp. |
OBSERVER_ERROR | Một listener hoặc callback vòng đời đã ném lỗi. |
OPERATION_ABORTED | Thao tác lưu trữ đã bị hủy. |
QUEUE_FULL | Có nhiều thao tác chờ hơn mức maxPendingOperations cho phép. |
REENTRANT_SETTER | Một updater state cố thay đổi chính store đó trong lúc đang chạy. |
SCOPE_DESTROYED | Một scope đã hủy được dùng để tạo store. |
SEQUENCE_EXHAUSTED | Chuỗi nội bộ đã hết định danh. |
STORAGE_BLOCKED | Lời gọi adapter trước đó chưa kết thúc sau khi hết thời gian hoặc bị hủy. |
STORAGE_TIMEOUT | Thao tác kéo dài hơn operationTimeoutMs. |
STORAGE_UNAVAILABLE | Không dùng được bộ nhớ lưu trữ ở đây; store vẫn tiếp tục chạy trong bộ nhớ. |
STORAGE_VALUE_TOO_LARGE | Giá trị đã mã hóa vượt quá maxStorageCharacters. |
STORAGE_VERSION_MISMATCH | Bản ghi có phiên bản khác và không hàm migrate nào xử lý được. |
STORE_DESTROYED | Một store đã hủy được đăng ký hoặc được yêu cầu dùng bộ nhớ lưu trữ. |