Make large G-code loading and execution robust
This commit is contained in:
@@ -239,6 +239,9 @@ export function App() {
|
||||
.then(() => dispatch("PROGRAM_RUN", {}, false))
|
||||
.catch(() => undefined);
|
||||
};
|
||||
const clearLoadedPreview = async () => {
|
||||
await operationController.execute("VISUAL_CLEAR", {}, { state: axisState, gate: false });
|
||||
};
|
||||
const loadCase = async () => {
|
||||
if (programLoading || programRunning) return;
|
||||
setProgramLoading(true);
|
||||
@@ -256,6 +259,7 @@ export function App() {
|
||||
const operation = await operationController.execute("LOAD_WORKSPACE", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) }, { state: axisState, gate: false });
|
||||
const resultPayload = (operation.response as { payload?: { configuration?: { state?: string } } }).payload;
|
||||
setProgramText(normalizedSource); setProgramPath(PROGRAM_PATH); setPlotCleared(false);
|
||||
await clearLoadedPreview();
|
||||
await operationController.execute("PROGRAM_LOAD", { source: normalizedSource, path: PROGRAM_PATH }, { state: axisState, gate: false });
|
||||
setOperationTrace(operationController.exportTrace());
|
||||
setCommandStatus("PROGRAM_LOAD acknowledged");
|
||||
@@ -277,6 +281,7 @@ export function App() {
|
||||
const source = normalizeProgramSource(await response.text());
|
||||
if (!source.trim()) throw new Error("program_asset_empty");
|
||||
setProgramText(source); setProgramPath(path); setPlotCleared(false);
|
||||
await clearLoadedPreview();
|
||||
await operationController.execute("PROGRAM_LOAD", { source, path }, { state: axisState, gate: false });
|
||||
setOperationTrace(operationController.exportTrace());
|
||||
setCommandStatus("PROGRAM_LOAD acknowledged");
|
||||
@@ -291,7 +296,7 @@ export function App() {
|
||||
setProgramLoading(true);
|
||||
setCommandStatus("PROGRAM_LOAD pending: waiting for LinuxCNC WASM preview");
|
||||
setPlotCleared(false);
|
||||
void dispatch("PROGRAM_LOAD", { source: programText, path: programPath })
|
||||
void clearLoadedPreview().then(() => dispatch("PROGRAM_LOAD", { source: programText, path: programPath }))
|
||||
.then(() => setCaseStatus(`${programPath} loaded through linuxcnc-wasm`))
|
||||
.catch(() => undefined)
|
||||
.finally(() => setProgramLoading(false));
|
||||
|
||||
@@ -56,7 +56,13 @@ export class OperationLedger {
|
||||
entry.phase = "verified";
|
||||
entry.status = response?.payload?.status === "error" || response?.kind === "ERROR" ? "failed" : "verified";
|
||||
entry.result_hash = fnv1a64(response?.payload ?? {});
|
||||
entry.response = clone(response);
|
||||
const payload = response?.payload;
|
||||
// High-frequency fixed-tick responses are deltas. Keep only the compact
|
||||
// operation evidence in the ledger; the full delta is already delivered
|
||||
// to the client and retained by the frontend trace window.
|
||||
entry.response = payload?.snapshot_mode === "motion_delta"
|
||||
? { ...response, payload: { status: payload.status, snapshot_mode: payload.snapshot_mode, simulation_tick: response.simulation_tick ?? null, program: payload.program ? { current_line: payload.program.current_line, program_status: payload.program.program_status, state_hash: payload.program.state_hash } : null } }
|
||||
: clone(response);
|
||||
return clone(entry);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,11 +45,13 @@ export class XyzacCommandLedger extends OperationLedger {
|
||||
return { status: "reconcile_required", operation_id: operationId, retry_allowed: false, reconciliation };
|
||||
}
|
||||
|
||||
audit({ includeResponses = true } = {}) {
|
||||
audit({ includeResponses = true, maxEntries = Number.POSITIVE_INFINITY } = {}) {
|
||||
const exported = super.export();
|
||||
const pending = this.pending();
|
||||
const entries = includeResponses ? exported.entries : exported.entries.map((entry) => { const { response, ...summary } = entry; return summary; });
|
||||
const unsigned = { schema: XYZAC_COMMAND_LEDGER_SCHEMA, operation_schema: LEDGER_SCHEMA, phases: [...LEDGER_PHASES], scope: this.scope, entries, pending_count: pending.length };
|
||||
const totalEntries = exported.entries.length;
|
||||
const windowed = Number.isFinite(maxEntries) && maxEntries >= 0 ? exported.entries.slice(-Math.floor(maxEntries)) : exported.entries;
|
||||
const entries = includeResponses ? windowed : windowed.map((entry) => { const { response, ...summary } = entry; return summary; });
|
||||
const unsigned = { schema: XYZAC_COMMAND_LEDGER_SCHEMA, operation_schema: LEDGER_SCHEMA, phases: [...LEDGER_PHASES], scope: this.scope, entries, entry_count: totalEntries, truncated: entries.length < totalEntries, pending_count: pending.length };
|
||||
return { ...unsigned, state_hash: fnv1a64(unsigned) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export class XyzacSession extends SimSession {
|
||||
// every previous response inside the stored response object.
|
||||
const payload = { ...response.payload };
|
||||
payload.xyzac_session = this.authority();
|
||||
payload.xyzac_ledger = this.ledger.audit({ includeResponses: input.kind !== "SIM_STEP" });
|
||||
payload.xyzac_ledger = this.ledger.audit({ includeResponses: input.kind !== "SIM_STEP", maxEntries: input.kind === "SIM_STEP" ? 32 : 2048 });
|
||||
payload.xyzac_scheduler = this.scheduler.export();
|
||||
return { ...response, payload };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user