fix: add timeout for device responses

This commit is contained in:
2024-03-05 18:12:56 +01:00
parent 7256dc50d4
commit 6ac2cd1993
3 changed files with 68 additions and 46 deletions

View File

@@ -40,6 +40,16 @@ export async function canAutoConnect() {
return getViablePorts().then(it => it.length === 1) return getViablePorts().then(it => it.length === 1)
} }
function timeout<T>(promise: Promise<T>, ms: number): Promise<T> {
let timer: number
return Promise.race([
promise,
new Promise<T>((_, reject) => {
timer = setTimeout(() => reject(new Error("Timeout")), ms) as unknown as number
}),
]).finally(() => clearTimeout(timer))
}
export class CharaDevice { export class CharaDevice {
private port!: SerialPort private port!: SerialPort
private reader!: ReadableStreamDefaultReader<string> private reader!: ReadableStreamDefaultReader<string>
@@ -124,7 +134,8 @@ export class CharaDevice {
} }
private async internalRead() { private async internalRead() {
const {value} = await this.reader.read() try {
const {value} = await timeout(this.reader.read(), 5000)
serialLog.update(it => { serialLog.update(it => {
it.push({ it.push({
type: "output", type: "output",
@@ -133,6 +144,15 @@ export class CharaDevice {
return it return it
}) })
return value! return value!
} catch (e) {
serialLog.update(it => {
it.push({
type: "output",
value: `${e}`,
})
return it
})
}
} }
/** /**
@@ -169,7 +189,10 @@ export class CharaDevice {
} }
const send = this.internalSend.bind(this) const send = this.internalSend.bind(this)
const read = this.internalRead.bind(this) const read = this.internalRead.bind(this)
const exec = new Promise<T>(async resolve => { let resolveLock: (result: true) => void
this.lock = new Promise<true>(resolve => {
resolveLock = resolve
})
let result!: T let result!: T
try { try {
if (this.suspendDebounceId) { if (this.suspendDebounceId) {
@@ -189,11 +212,9 @@ export class CharaDevice {
return true return true
}) })
}, this.suspendDebounce) as any }, this.suspendDebounce) as any
resolve(result) resolveLock!(true)
return result
} }
})
this.lock = exec.then(() => true)
return exec
} }
/** /**

View File

@@ -1,21 +1,26 @@
export class SemVer { export class SemVer {
major: number major = 0
minor: number minor = 0
patch: number patch = 0
preRelease?: string preRelease?: string
meta?: string meta?: string
constructor(versionString: 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( /^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+))?$/.exec(
versionString, versionString,
)! )
if (!result) {
console.error("Invalid version string:", versionString)
} else {
const [, major, minor, patch, preRelease, meta] = result
this.major = Number.parseInt(major) this.major = Number.parseInt(major)
this.minor = Number.parseInt(minor) this.minor = Number.parseInt(minor)
this.patch = Number.parseInt(patch) this.patch = Number.parseInt(patch)
if (preRelease) this.preRelease = preRelease if (preRelease) this.preRelease = preRelease
if (meta) this.meta = meta if (meta) this.meta = meta
} }
}
toString() { toString() {
return ( return (

View File

@@ -69,10 +69,6 @@
$: chordActions = chord?.actions.slice(chord.actions.lastIndexOf(0) + 1).toSorted(compare) $: chordActions = chord?.actions.slice(chord.actions.lastIndexOf(0) + 1).toSorted(compare)
$: compoundIndices = chord?.actions.slice(0, chord.actions.indexOf(0)) $: compoundIndices = chord?.actions.slice(0, chord.actions.indexOf(0))
$: {
console.log(chord?.actions, chordActions, compoundIndices)
}
</script> </script>
<button <button