feat(kanban): bound durable replay
req: sync/014\nreq: performance/005
This commit is contained in:
@@ -3,6 +3,8 @@ const COMMANDS = "commands";
|
||||
const META = "meta";
|
||||
const COMMAND_SCHEMA = 1;
|
||||
const EXPORT_SCHEMA = 1;
|
||||
const MAX_REPLAY_COMMANDS = 64;
|
||||
const REPLAY_BUDGET_MS = 100;
|
||||
const SESSION = "hemx-kanban-session-v1";
|
||||
const ROOT = '[data-hemx-root][data-hemx-client-module="/kanban_client.js"]';
|
||||
|
||||
@@ -110,6 +112,13 @@ async function storedCommands(database) {
|
||||
return commands.sort((left, right) => left.causal - right.causal);
|
||||
}
|
||||
|
||||
class ReplayLimitError extends Error {
|
||||
constructor(actual) {
|
||||
super(`durable replay limit exceeded: ${actual} > ${MAX_REPLAY_COMMANDS}`);
|
||||
this.name = "ReplayLimitError";
|
||||
}
|
||||
}
|
||||
|
||||
function invalidCommand(command, field) {
|
||||
const id = command && typeof command.id === "string" && command.id ? command.id : "record";
|
||||
throw new Error(`invalid durable command ${id}: ${field}`);
|
||||
@@ -279,9 +288,17 @@ async function start() {
|
||||
if (typeof wasmHandler !== "function") throw new Error("reorder_card WASM handler is not registered");
|
||||
const database = await databasePromise;
|
||||
installRecoveryControls(root, database);
|
||||
root.setAttribute("data-kanban-replay-limit", String(MAX_REPLAY_COMMANDS));
|
||||
try {
|
||||
const commands = await storedCommands(database);
|
||||
if (commands.length > MAX_REPLAY_COMMANDS) throw new ReplayLimitError(commands.length);
|
||||
commands.forEach(validate);
|
||||
const replayStarted = performance.now();
|
||||
for (const command of commands) window.hemx.applyBatch(await project(root, wasmHandler, command), root);
|
||||
const replayMs = performance.now() - replayStarted;
|
||||
root.setAttribute("data-kanban-replay-ms", replayMs.toFixed(3));
|
||||
root.setAttribute("data-kanban-replay-budget-ms", String(REPLAY_BUDGET_MS));
|
||||
root.toggleAttribute("data-kanban-replay-over-budget", replayMs > REPLAY_BUDGET_MS);
|
||||
root.setAttribute("data-kanban-command-count", String(commands.length));
|
||||
root.setAttribute("data-kanban-command-ready", "");
|
||||
await offlineReady;
|
||||
|
||||
Reference in New Issue
Block a user