From 6ac2cd19938cda633ead515ee7e222a8e393f7c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Tue, 5 Mar 2024 18:12:56 +0100 Subject: [PATCH] fix: add timeout for device responses --- src/lib/serial/device.ts | 85 ++++++++++++------- src/lib/serial/sem-ver.ts | 25 +++--- .../config/chords/ChordActionEdit.svelte | 4 - 3 files changed, 68 insertions(+), 46 deletions(-) diff --git a/src/lib/serial/device.ts b/src/lib/serial/device.ts index 2480ddd7..e0f14da0 100644 --- a/src/lib/serial/device.ts +++ b/src/lib/serial/device.ts @@ -40,6 +40,16 @@ export async function canAutoConnect() { return getViablePorts().then(it => it.length === 1) } +function timeout(promise: Promise, ms: number): Promise { + let timer: number + return Promise.race([ + promise, + new Promise((_, reject) => { + timer = setTimeout(() => reject(new Error("Timeout")), ms) as unknown as number + }), + ]).finally(() => clearTimeout(timer)) +} + export class CharaDevice { private port!: SerialPort private reader!: ReadableStreamDefaultReader @@ -124,15 +134,25 @@ export class CharaDevice { } private async internalRead() { - const {value} = await this.reader.read() - serialLog.update(it => { - it.push({ - type: "output", - value: value!, + try { + const {value} = await timeout(this.reader.read(), 5000) + serialLog.update(it => { + it.push({ + type: "output", + value: value!, + }) + return it }) - return it - }) - return value! + return value! + } catch (e) { + serialLog.update(it => { + it.push({ + type: "output", + value: `${e}`, + }) + return it + }) + } } /** @@ -169,31 +189,32 @@ export class CharaDevice { } const send = this.internalSend.bind(this) const read = this.internalRead.bind(this) - const exec = new Promise(async resolve => { - let result!: T - try { - if (this.suspendDebounceId) { - clearTimeout(this.suspendDebounceId) - } else { - await this.wake() - } - result = await callback(send, read) - } finally { - delete this.lock - this.suspendDebounceId = setTimeout(() => { - // cannot be locked here as all the code until clearTimeout is sync - console.assert(this.lock === undefined) - this.lock = this.suspend().then(() => { - delete this.lock - delete this.suspendDebounceId - return true - }) - }, this.suspendDebounce) as any - resolve(result) - } + let resolveLock: (result: true) => void + this.lock = new Promise(resolve => { + resolveLock = resolve }) - this.lock = exec.then(() => true) - return exec + let result!: T + try { + if (this.suspendDebounceId) { + clearTimeout(this.suspendDebounceId) + } else { + await this.wake() + } + result = await callback(send, read) + } finally { + delete this.lock + this.suspendDebounceId = setTimeout(() => { + // cannot be locked here as all the code until clearTimeout is sync + console.assert(this.lock === undefined) + this.lock = this.suspend().then(() => { + delete this.lock + delete this.suspendDebounceId + return true + }) + }, this.suspendDebounce) as any + resolveLock!(true) + return result + } } /** diff --git a/src/lib/serial/sem-ver.ts b/src/lib/serial/sem-ver.ts index b5099ab7..b1e4aaec 100644 --- a/src/lib/serial/sem-ver.ts +++ b/src/lib/serial/sem-ver.ts @@ -1,20 +1,25 @@ export class SemVer { - major: number - minor: number - patch: number + major = 0 + minor = 0 + patch = 0 preRelease?: string meta?: string constructor(versionString: string) { - const [, major, minor, patch, preRelease, meta] = + const result = /^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+))?$/.exec( versionString, - )! - this.major = Number.parseInt(major) - this.minor = Number.parseInt(minor) - this.patch = Number.parseInt(patch) - if (preRelease) this.preRelease = preRelease - if (meta) this.meta = meta + ) + if (!result) { + console.error("Invalid version string:", versionString) + } else { + const [, major, minor, patch, preRelease, meta] = result + this.major = Number.parseInt(major) + this.minor = Number.parseInt(minor) + this.patch = Number.parseInt(patch) + if (preRelease) this.preRelease = preRelease + if (meta) this.meta = meta + } } toString() { diff --git a/src/routes/config/chords/ChordActionEdit.svelte b/src/routes/config/chords/ChordActionEdit.svelte index 385e9a43..018cd599 100644 --- a/src/routes/config/chords/ChordActionEdit.svelte +++ b/src/routes/config/chords/ChordActionEdit.svelte @@ -69,10 +69,6 @@ $: chordActions = chord?.actions.slice(chord.actions.lastIndexOf(0) + 1).toSorted(compare) $: compoundIndices = chord?.actions.slice(0, chord.actions.indexOf(0)) - - $: { - console.log(chord?.actions, chordActions, compoundIndices) - }