From 19211ad7c96cdef106af29e0026e80343bd3c354 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Fri, 10 Nov 2023 20:00:13 +0000 Subject: [PATCH] fix: local file playback race (#18557) --- .../sessionRecordingFilePlaybackLogic.ts | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/frontend/src/scenes/session-recordings/file-playback/sessionRecordingFilePlaybackLogic.ts b/frontend/src/scenes/session-recordings/file-playback/sessionRecordingFilePlaybackLogic.ts index 8d4d1ebe5c878..54ef82ab8da18 100644 --- a/frontend/src/scenes/session-recordings/file-playback/sessionRecordingFilePlaybackLogic.ts +++ b/frontend/src/scenes/session-recordings/file-playback/sessionRecordingFilePlaybackLogic.ts @@ -77,6 +77,40 @@ export const parseExportedSessionRecording = (fileData: string): ExportedSession } } +/** + * There's a race between loading the file causing the React component to be rendered that mounts the dataLogic + * and this logic loading the file and wanting to tell the logic about it + * + * This method waits for the dataLogic to be mounted and returns it + * + * in practice, it will only wait for 1-2 retries + * but a timeout is provided to avoid waiting forever when something breaks + */ +const waitForDataLogic = async (playerKey: string): Promise> => { + const maxRetries = 20 // 2 seconds / 100 ms per retry + let retries = 0 + let dataLogic = null + + while (retries < maxRetries) { + dataLogic = sessionRecordingDataLogic.findMounted({ + sessionRecordingId: '', + playerKey: playerKey, + }) + + if (dataLogic !== null) { + // eslint-disable-next-line no-console + console.log('found after retries', retries) + return dataLogic + } + + // Wait for a short period before trying again + await new Promise((resolve) => setTimeout(resolve, 1)) + retries++ + } + + throw new Error('Timeout reached: dataLogic is still null after 2 seconds') +} + export const sessionRecordingFilePlaybackLogic = kea([ path(['scenes', 'session-recordings', 'detail', 'sessionRecordingDetailLogic']), connect({ @@ -125,12 +159,8 @@ export const sessionRecordingFilePlaybackLogic = kea ({ - loadFromFileSuccess: () => { - // Once we loaded the file we set the logic - const dataLogic = sessionRecordingDataLogic.findMounted({ - sessionRecordingId: '', - playerKey: values.playerKey, - }) + loadFromFileSuccess: async () => { + const dataLogic = await waitForDataLogic(values.playerKey) if (!dataLogic || !values.sessionRecording) { return