瀏覽代碼

fix(mobile): reload web app if old db worker is still running

when switching back to the app.
Tienson Qin 1 周之前
父節點
當前提交
4e5237e82a
共有 3 個文件被更改,包括 57 次插入40 次删除
  1. 1 1
      src/main/frontend/handler/worker.cljs
  2. 49 38
      src/main/frontend/persist_db/browser.cljs
  3. 7 1
      src/main/frontend/state.cljs

+ 1 - 1
src/main/frontend/handler/worker.cljs

@@ -56,7 +56,7 @@
 
 (defmethod handle :record-worker-client-id [_ _worker data]
   (when-let [client-id (:client-id data)]
-    (reset! state/*db-worker-client-id client-id)))
+    (state/set-db-worker-client-id! client-id)))
 
 (defmethod handle :capture-error [_ _worker data]
   (state/pub-event! [:capture-error data]))

+ 49 - 38
src/main/frontend/persist_db/browser.cljs

@@ -101,46 +101,57 @@
     (set! (.-pfs js/window) pfs)
     (set! (.-workerThread js/window) worker-thread)))
 
+(defn- reload-app-if-old-db-worker-exists
+  []
+  (when-let [client-id @state/*db-worker-client-id]
+    (js/navigator.locks.request client-id #js {:mode "exclusive"
+                                               :ifAvailable true}
+                                (fn [lock]
+                                  (when-not lock
+                                    (js/window.location.reload))))))
+
 (defn start-db-worker!
   []
-  (when-not util/node-test?
-    (let [worker-url (if config/publishing? "static/js/db-worker.js" "js/db-worker.js")
-          worker (js/Worker. (str worker-url "?electron=" (util/electron?) "&publishing=" config/publishing?))
-          _ (set-worker-fs worker)
-          wrapped-worker* (Comlink/wrap worker)
-          wrapped-worker (fn [qkw direct-pass? & args]
-                           (p/let [result (.remoteInvoke ^js wrapped-worker*
-                                                         (str (namespace qkw) "/" (name qkw))
-                                                         direct-pass?
-                                                         (cond
-                                                           (= qkw :thread-api/set-infer-worker-proxy)
-                                                           (first args)
-                                                           direct-pass?
-                                                           (into-array args)
-                                                           :else
-                                                           (ldb/write-transit-str args)))]
-                             (if direct-pass?
-                               result
-                               (ldb/read-transit-str result))))
-          t1 (util/time-ms)]
-      (Comlink/expose #js{"remoteInvoke" thread-api/remote-function} worker)
-      (worker-handler/handle-message! worker wrapped-worker)
-      (reset! state/*db-worker wrapped-worker)
-      (-> (p/let [_ (state/<invoke-db-worker :thread-api/init config/RTC-WS-URL)
-                  _ (sync-app-state!)
-                  _ (log/debug "init worker spent" (str (- (util/time-ms) t1) "ms"))
-                  _ (sync-ui-state!)
-                  _ (ask-persist-permission!)
-                  _ (state/pub-event! [:graph/sync-context])]
-            (ldb/register-transact-fn!
-             (fn worker-transact!
-               [repo tx-data tx-meta]
-               (db-transact/transact transact!
-                                     (if (string? repo) repo (state/get-current-repo))
-                                     tx-data
-                                     (assoc tx-meta :client-id (:client-id @state/state))))))
-          (p/catch (fn [error]
-                     (log/error :init-sqlite-wasm-error ["Can't init SQLite wasm" error])))))))
+  (p/do!
+   (reload-app-if-old-db-worker-exists)
+   (when-not util/node-test?
+     (let [worker-url (if config/publishing? "static/js/db-worker.js" "js/db-worker.js")
+           worker (js/Worker. (str worker-url "?electron=" (util/electron?) "&publishing=" config/publishing?))
+           _ (set-worker-fs worker)
+           wrapped-worker* (Comlink/wrap worker)
+           wrapped-worker (fn [qkw direct-pass? & args]
+                            (p/let [result (.remoteInvoke ^js wrapped-worker*
+                                                          (str (namespace qkw) "/" (name qkw))
+                                                          direct-pass?
+                                                          (cond
+                                                            (= qkw :thread-api/set-infer-worker-proxy)
+                                                            (first args)
+                                                            direct-pass?
+                                                            (into-array args)
+                                                            :else
+                                                            (ldb/write-transit-str args)))]
+                              (if direct-pass?
+                                result
+                                (ldb/read-transit-str result))))
+           t1 (util/time-ms)]
+       (Comlink/expose #js{"remoteInvoke" thread-api/remote-function} worker)
+       (worker-handler/handle-message! worker wrapped-worker)
+       (reset! state/*db-worker wrapped-worker)
+       (-> (p/let [_ (state/<invoke-db-worker :thread-api/init config/RTC-WS-URL)
+                   _ (sync-app-state!)
+                   _ (log/debug "init worker spent" (str (- (util/time-ms) t1) "ms"))
+                   _ (sync-ui-state!)
+                   _ (ask-persist-permission!)
+                   _ (state/pub-event! [:graph/sync-context])]
+             (ldb/register-transact-fn!
+              (fn worker-transact!
+                [repo tx-data tx-meta]
+                (db-transact/transact transact!
+                                      (if (string? repo) repo (state/get-current-repo))
+                                      tx-data
+                                      (assoc tx-meta :client-id (:client-id @state/state))))))
+           (p/catch (fn [error]
+                      (log/error :init-sqlite-wasm-error ["Can't init SQLite wasm" error]))))))))
 
 (defn <check-webgpu-available?
   []

+ 7 - 1
src/main/frontend/state.cljs

@@ -32,7 +32,7 @@
 (defonce *profile-state (volatile! {}))
 
 (defonce *db-worker (atom nil))
-(defonce *db-worker-client-id (atom nil))
+(defonce *db-worker-client-id (atom (storage/get :db-worker-client-id)))
 (defonce *editor-info (atom nil))
 (defonce app-ready-promise (p/deferred))
 
@@ -2360,3 +2360,9 @@ Similar to re-frame subscriptions"
   [days]
   (reset! (:ui/highlight-recent-days @state) days)
   (storage/set :ui/highlight-recent-days days))
+
+(defn set-db-worker-client-id!
+  [new-id]
+  (when new-id
+    (reset! *db-worker-client-id new-id)
+    (storage/set :db-worker-client-id new-id)))