From edf2122059359ab5583aaa53f6b1c550b85bc2cc Mon Sep 17 00:00:00 2001
From: Matiss Janis Aboltins <matiss@mja.lv>
Date: Wed, 22 Mar 2023 19:59:52 +0000
Subject: [PATCH] :bug: (dev-server) retry loading backend script in web-worker
 (#806)

Co-authored-by: Jed Fox <git@jedfox.com>
---
 packages/desktop-client/src/browser-server.js | 42 ++++++++++++++++++-
 upcoming-release-notes/806.md                 |  6 +++
 2 files changed, 46 insertions(+), 2 deletions(-)
 create mode 100644 upcoming-release-notes/806.md

diff --git a/packages/desktop-client/src/browser-server.js b/packages/desktop-client/src/browser-server.js
index 8ccee8c34..7ac16a3e7 100644
--- a/packages/desktop-client/src/browser-server.js
+++ b/packages/desktop-client/src/browser-server.js
@@ -1,7 +1,42 @@
 /* globals importScripts, backend */
 let hasInitialized = false;
 
-self.addEventListener('message', e => {
+/**
+ * Sometimes the frontend build is way faster than backend.
+ * This results in the frontend starting up before backend is
+ * finished and thus the backend script is not available.
+ *
+ * The goal of this function is to retry X amount of times
+ * to retrieve the backend script with a small delay.
+ */
+const importScriptsWithRetry = async (script, { maxRetries = 5 } = {}) => {
+  try {
+    importScripts(script);
+  } catch (e) {
+    // Break if maxRetries has exceeded
+    if (maxRetries <= 0) {
+      throw e;
+    } else {
+      console.groupCollapsed(
+        `Failed to load backend, will retry ${maxRetries} more time(s)`,
+      );
+      console.log(e);
+      console.groupEnd();
+    }
+
+    // Attempt to retry after a small delay
+    await new Promise(resolve =>
+      setTimeout(async () => {
+        await importScriptsWithRetry(script, {
+          maxRetries: maxRetries - 1,
+        });
+        resolve();
+      }, 5000),
+    );
+  }
+};
+
+self.addEventListener('message', async e => {
   if (!hasInitialized) {
     let msg = e.data;
 
@@ -19,7 +54,10 @@ self.addEventListener('message', e => {
         return;
       }
 
-      importScripts(`${msg.publicUrl}/kcab/kcab.worker.${hash}.js`);
+      await importScriptsWithRetry(
+        `${msg.publicUrl}/kcab/kcab.worker.${hash}.js`,
+        { maxRetries: isDev ? 5 : 0 },
+      );
 
       backend.initApp(version, isDev, self).catch(err => {
         console.log(err);
diff --git a/upcoming-release-notes/806.md b/upcoming-release-notes/806.md
new file mode 100644
index 000000000..7c4edfcc4
--- /dev/null
+++ b/upcoming-release-notes/806.md
@@ -0,0 +1,6 @@
+---
+category: Maintenance
+authors: [MatissJanis]
+---
+
+Retry loading backend script in web-workers (for local dev server)
-- 
GitLab