From 1964c9c4857f179d67fd3be55d28119dfb533af0 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 12 Apr 2021 13:24:10 -0500 Subject: [PATCH] Add timeout while waiting for checksum This adds a timeout while waiting for the checksum from the hub when downloading and running a program. Without this, we can get stuck in the "loading" state if the hub doesn't respond as expected. This can happen, for example, if a program is started with the hub button at the same time as the start button in Pybricks Code is pressed. Issue: https://github.com/pybricks/support/issues/301 --- src/hub/sagas.ts | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/hub/sagas.ts b/src/hub/sagas.ts index 55eedb29..cd795dcd 100644 --- a/src/hub/sagas.ts +++ b/src/hub/sagas.ts @@ -4,6 +4,7 @@ import { SagaGenerator, actionChannel, + delay, getContext, put, race, @@ -108,7 +109,19 @@ function* downloadAndRun(_action: HubDownloadAndRunAction): Generator { return; } - const checksumAction = yield* take(checksumChannel); + const { checksumAction, checksumTimeout } = yield* race({ + checksumAction: take(checksumChannel), + checksumTimeout: delay(1000), + }); + + if (checksumTimeout) { + console.error(`timeout waiting for checksum`); + yield* put(didFailToFinishDownload()); + return; + } + + defined(checksumAction); + if (checksumAction.checksum !== (0xff ^ xor8(sizeBuf))) { console.error( `bad checksum ${checksumAction.checksum} vs ${0xff ^ xor8(sizeBuf)}`, @@ -136,7 +149,20 @@ function* downloadAndRun(_action: HubDownloadAndRunAction): Generator { } // TODO: dispatch progress } - const checksumAction = yield* take(checksumChannel); + + const { checksumAction, checksumTimeout } = yield* race({ + checksumAction: take(checksumChannel), + checksumTimeout: delay(1000), + }); + + if (checksumTimeout) { + console.error(`timeout waiting for checksum`); + yield* put(didFailToFinishDownload()); + return; + } + + defined(checksumAction); + if (checksumAction.checksum !== (0xff ^ xor8(chunk))) { console.error( `bad checksum ${checksumAction.checksum} vs ${0xff ^ xor8(chunk)}`,