Skip to content

Commit 796da85

Browse files
Avoid disconnect during flash. (#252)
Somewhat speculative fix as I can't get the visibilitychange event to trigger during flash anymore. It seems to occur at the end of flash. But given there's async work in the flash it makes sense that it can occur. I've added logging for the visibility change work. I think we'd like to drop all this if we could fix the underlying cause of #89. Fixes #223
1 parent 625cd98 commit 796da85

File tree

1 file changed

+46
-22
lines changed

1 file changed

+46
-22
lines changed

src/device/device.ts

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -203,21 +203,33 @@ export class MicrobitWebUSBConnection
203203
this.emit(EVENT_SERIAL_DATA, data);
204204
};
205205

206+
private flashing: boolean = false;
207+
private disconnectAfterFlash: boolean = false;
206208
private visibilityReconnect: boolean = false;
207209
private visibilityChangeListener = () => {
208210
if (document.visibilityState === "visible") {
209211
if (
210212
this.visibilityReconnect &&
211213
this.status !== ConnectionStatus.CONNECTED
212214
) {
215+
this.disconnectAfterFlash = false;
213216
this.visibilityReconnect = false;
214-
this.connect();
217+
if (!this.flashing) {
218+
this.log("Reconnecting visible tab");
219+
this.connect();
220+
}
215221
}
216222
} else {
217223
if (!this.unloading && this.status === ConnectionStatus.CONNECTED) {
218-
this.disconnect().then(() => {
219-
this.visibilityReconnect = true;
220-
});
224+
if (!this.flashing) {
225+
this.log("Disconnecting hidden tab");
226+
this.disconnect().then(() => {
227+
this.visibilityReconnect = true;
228+
});
229+
} else {
230+
this.log("Scheduling disconnect of hidden tab for after flash");
231+
this.disconnectAfterFlash = true;
232+
}
221233
}
222234
}
223235
};
@@ -311,20 +323,25 @@ export class MicrobitWebUSBConnection
311323
progress: (percentage: number | undefined) => void;
312324
}
313325
): Promise<void> {
314-
const startTime = new Date().getTime();
326+
this.flashing = true;
327+
try {
328+
const startTime = new Date().getTime();
315329

316-
await this.withEnrichedErrors(() =>
317-
this.flashInternal(dataSource, options)
318-
);
330+
await this.withEnrichedErrors(() =>
331+
this.flashInternal(dataSource, options)
332+
);
319333

320-
const flashTime = new Date().getTime() - startTime;
321-
this.logging.event({
322-
type: "WebUSB-time",
323-
detail: {
324-
flashTime,
325-
},
326-
});
327-
this.logging.log("Flash complete");
334+
const flashTime = new Date().getTime() - startTime;
335+
this.logging.event({
336+
type: "WebUSB-time",
337+
detail: {
338+
flashTime,
339+
},
340+
});
341+
this.logging.log("Flash complete");
342+
} finally {
343+
this.flashing = false;
344+
}
328345
}
329346

330347
private async flashInternal(
@@ -356,12 +373,19 @@ export class MicrobitWebUSBConnection
356373
} finally {
357374
progress(undefined);
358375

359-
// This might not strictly be "reinstating". We should make this
360-
// behaviour configurable when pulling out a library.
361-
this.log("Reinstating serial after flash");
362-
if (this.connection.daplink) {
363-
await this.connection.daplink.connect();
364-
await this.startSerialInternal();
376+
if (this.disconnectAfterFlash) {
377+
this.log("Disconnecting after flash due to tab visibility");
378+
this.disconnectAfterFlash = false;
379+
await this.disconnect();
380+
this.visibilityReconnect = true;
381+
} else {
382+
// This might not strictly be "reinstating". We should make this
383+
// behaviour configurable when pulling out a library.
384+
this.log("Reinstating serial after flash");
385+
if (this.connection.daplink) {
386+
await this.connection.daplink.connect();
387+
await this.startSerialInternal();
388+
}
365389
}
366390
}
367391
}

0 commit comments

Comments
 (0)