restate / v1.0.0
Spolehlivost by design
Co restate zaručuje, když je úložiště pomalé, selhává nebo chybí, a jak číst chyby, které hlásí.
Na této stránce
ZárukyUložení v pořadíVyzkoušejteKdyž načítání selžeUložit a zavřítŽádné úložiště k dispoziciValidace a migrace uložených datVlastní úložištěLimity a časové limityKódy chybZáruky
Toto chování je součástí kontraktu 1.0 a pokrývají ho testy balíčku.
| Situace | Co restate udělá |
|---|---|
Několik uložení za sebou | Provede je v pořadí pro každý store; uložení ve frontě zapíše nejnovější hodnotu. |
Záznam se nenačetl | autoSave a hromadná uložení ho přeskočí s LOAD_FAILED; nahradí ho jen explicitní save(). |
Komponenta se během uložení odpojí | Vyžádané uložení se dokončí; pozdější zápisy do zničeného store se ignorují. |
Úložiště není dostupné | Store funguje v paměti, status().available je false a uložení se odmítají. |
Adaptér se zasekne | Operaci vyprší čas po operationTimeoutMs a další práce počká, až adaptér skončí. |
Příliš mnoho čekající práce | Nové operace se odmítnou s QUEUE_FULL, místo aby fronta rostla bez omezení. |
Uložení v pořadí
Operace jednoho store se nikdy nepřekrývají. Uložení spuštěné, zatímco jiné čeká, vezme nejnovější hodnotu, takže ukládání při každé změně zapíše poslední stav bez zahlcení fronty.
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 writesVyzkoušejte
Zpomalte úložiště, nechte zápisy selhávat nebo úložiště úplně odeberte.
Příprava příkladu…
Když načítání selže
restateManager.ready se odmítne s BULK_OPERATION_FAILED a vypíše každý store, který selhal. Dokud se ten záznam nenačte, autoSave a saveAll ho nenahradí a nahlásí LOAD_FAILED.
Zkuste to znovu přes initialize(), chcete-li úpravy zachovat a uložit, zavolejte restore(), chcete-li je zahodit, nebo save(), chcete-li záznam záměrně přepsat.
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);
}
}Uložit a zavřít
Uložení vyžádané před odpojením se i tak dokončí, takže obsluha „Uložit a zavřít“ nemusí čekat.
function Document({ onClose }) {
const useDraft = useRestateScope((scope) => persistedRestate('', { scope, key: 'draft' }));
const saveAndClose = () => {
useDraft.save(); // finishes even after this component unmounts
onClose();
};
// …
}Validace a migrace uložených dat
version, migrate a validate vás chrání před starými nebo poškozenými záznamy. validate se spouští před uložením a po obnovení či migraci.
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),
},
);Vlastní úložiště
Poslouží jakýkoli objekt s getItem, setItem a removeItem. Metody mohou vracet hodnoty nebo Promise; isAvailable je volitelné.
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,
},
);Limity a časové limity
Nastavte, jak dlouho smí operace trvat, kolik jich smí čekat a jak velká smí být hodnota.
persistedRestate(value, {
key: 'draft',
operationTimeoutMs: 10_000, // default 30000
maxPendingOperations: 64, // default 256
maxStorageCharacters: 1_000_000,
});Kódy chyb
Chyby vytvořené restate mají name RestateError, code a u ukládaných store také key. Adaptéry úložiště a vaše callbacky mohou odmítat vlastními chybami.
| Kód | Význam |
|---|---|
BULK_OPERATION_FAILED | Hromadné volání jako restateManager.ready nebo saveAll mělo chyby; viz error.failures. |
INDEXEDDB_ABORTED | Transakce IndexedDB byla přerušena. |
INDEXEDDB_BLOCKED | Otevření databáze zablokovalo připojení v jiné kartě. |
INDEXEDDB_CONNECTION_CLOSING | Připojení k databázi se zavíralo, když požadavek začal. |
INDEXEDDB_OPEN_FAILED | Databázi se nepodařilo otevřít. |
INDEXEDDB_REQUEST_FAILED | Požadavek IndexedDB selhal. |
INDEXEDDB_STORE_MISSING | V již vytvořené databázi chybí object store. |
INVALID_STORAGE_RECORD | Uložený záznam není platný záznam restate. |
INVALID_STORED_VALUE | Hodnota neprošla validate. |
LIFECYCLE_LIMIT | Updater se opakovaně spouštěl a zastavoval. |
LOAD_FAILED | Záznam se nepodařilo načíst, takže ho automatické ani hromadné uložení nenahradilo. |
MMKV_UNAVAILABLE | react-native-mmkv se nepodařilo načíst. |
MULTIPLE_ERRORS | V jedné operaci selhalo více callbacků; viz error.errors. |
NOTIFICATION_LIMIT | Pozorovatelé v cyklu stále plánovali změny. |
OBSERVER_ERROR | Posluchač nebo callback životního cyklu vyhodil chybu. |
OPERATION_ABORTED | Operace s úložištěm byla zrušena. |
QUEUE_FULL | Čekalo více operací, než dovoluje maxPendingOperations. |
REENTRANT_SETTER | Updater stavu se během svého běhu pokusil změnit tentýž store. |
SCOPE_DESTROYED | K vytvoření store byl použit zničený scope. |
SEQUENCE_EXHAUSTED | Vnitřní sekvenci došly identifikátory. |
STORAGE_BLOCKED | Předchozí volání adaptéru se po vypršení času nebo zrušení nedokončilo. |
STORAGE_TIMEOUT | Operace trvala déle než operationTimeoutMs. |
STORAGE_UNAVAILABLE | Úložiště zde nelze použít; store dál funguje v paměti. |
STORAGE_VALUE_TOO_LARGE | Zakódovaná hodnota překračuje maxStorageCharacters. |
STORAGE_VERSION_MISMATCH | Záznam má jinou verzi a žádná funkce migrate ji neobsluhuje. |
STORE_DESTROYED | Došlo k odběru zničeného store nebo byl požádán o použití úložiště. |