Browse Source

enhance(rtc): retry rtc-start if graph is not ready yet(still creating)

rcmerci 1 year ago
parent
commit
2bb43dc6c5

+ 3 - 3
src/main/frontend/db_worker.cljs

@@ -602,10 +602,10 @@
      (when-let [conn (worker-state/get-datascript-conn repo)]
        (async/go
          (try
-           (let [state (<? (rtc-core/<init-state repo token false))]
-             (<? (rtc-updown/<async-upload-graph state repo conn remote-graph-name))
+           (let [state (<? (rtc-core/<init-state repo token false))
+                 r (<? (rtc-updown/<async-upload-graph state repo conn remote-graph-name))]
              (rtc-db-listener/listen-db-to-generate-ops repo conn)
-             (p/resolve! d :success))
+             (p/resolve! d r))
            (catch :default e
              (worker-util/post-message :notification
                                        [[:div

+ 18 - 6
src/main/frontend/handler/db_based/rtc.cljs

@@ -10,6 +10,7 @@
             [logseq.db.sqlite.common-db :as sqlite-common-db]
             [frontend.handler.notification :as notification]))
 
+
 (defn <rtc-create-graph!
   [repo]
   (when-let [^js worker @state/*db-worker]
@@ -43,18 +44,29 @@
     (.rtc-stop worker)))
 
 (defn <rtc-start!
-  [repo]
+  [repo & {:keys [retry] :or {retry 0}}]
   (when-let [^js worker @state/*db-worker]
     (when (ldb/get-graph-rtc-uuid (db/get-db repo))
       (user-handler/<wrap-ensure-id&access-token
         ;; TODO: `<rtc-stop!` can return a chan so that we can remove timeout
        (<rtc-stop!)
        (let [token (state/get-auth-id-token)]
-         (-> (.rtc-start worker repo token
-                         (state/sub [:ui/developer-mode?]))
-             (p/then (fn [result]
-                       (when (= "rtc-not-closed-yet" result)
-                         (js/setTimeout #(<rtc-start! repo) 200))))))))))
+         (p/let [result (.rtc-start worker repo token (state/sub [:ui/developer-mode?]))
+                 _ (case result
+                     "rtc-not-closed-yet"
+                     (js/setTimeout #(<rtc-start! repo) 200)
+                     ":graph-not-ready"
+                     (when (< retry 3)
+                       (let [delay (* 2000 (inc retry))]
+                         (prn "graph still creating, retry rtc-start in " delay "ms")
+                         (p/do! (p/delay delay)
+                                (<rtc-start! repo :retry (inc retry)))))
+
+                     (":break-rtc-loop" ":stop-rtc-loop")
+                     nil
+                     ;; else
+                     nil)]
+           nil))))))
 
 (defn <get-remote-graphs
   []

+ 47 - 34
src/main/frontend/worker/rtc/core.cljs

@@ -53,6 +53,7 @@
 ;;; exceptions ================================================================
 
 (def ex-break-rtc-loop (ex-info "break rtc loop" {:type ::break-rtc-loop}))
+(def ex-graph-not-ready (ex-info "graph still creating" {:type ::graph-not-ready}))
 
 ;;; exceptions (ends)
 
@@ -918,6 +919,11 @@
     (stop-rtc state)
     (throw ex-break-rtc-loop)))
 
+(defmethod handle-remote-genernal-exception :graph-not-ready [_ state]
+  (stop-rtc-helper state)
+  (stop-rtc state)
+  (throw ex-graph-not-ready))
+
 
 (defmethod handle-remote-genernal-exception nil [resp & _]
   (throw (ex-info "unknown exception from remote" {:resp resp})))
@@ -1005,7 +1011,8 @@
 (declare notify-main-thread)
 
 (defn <loop-for-rtc
-  ":loop-started-ch used to notify that rtc-loop started"
+  ":loop-started-ch used to notify that rtc-loop started.
+  return `:stop-rtc-loop`, `:break-rtc-loop`, `:graph-not-ready`"
   [state graph-uuid repo conn date-formatter & {:keys [loop-started-ch token]}]
   {:pre [(state-validator state)
          (some? graph-uuid)
@@ -1027,49 +1034,54 @@
       (reset! (:*graph-uuid state) graph-uuid)
       (let [resp (<? (ws/<send&receive state {:action "register-graph-updates"
                                               :graph-uuid graph-uuid}))]
+
         (try
-          (when (:ex-data resp) (handle-remote-genernal-exception resp state))
+          (when (:ex-data resp)
+            (handle-remote-genernal-exception resp state))
           (async/sub data-from-ws-pub "push-updates" push-data-from-ws-ch)
           (when loop-started-ch (async/close! loop-started-ch))
           (<?
            (go-try
-             (loop [push-client-ops-ch
-                    (make-push-client-ops-timeout-ch repo (not @*auto-push-client-ops?))]
-               (let [{:keys [push-data-from-ws client-op-update stop continue]}
-                     (async/alt!
-                       toggle-auto-push-client-ops-ch {:continue true}
-                       force-push-client-ops-ch {:client-op-update true}
-                       push-client-ops-ch ([v] (if (and @*auto-push-client-ops? (true? v))
-                                                 {:client-op-update true}
-                                                 {:continue true}))
-                       push-data-from-ws-ch ([v] {:push-data-from-ws v})
-                       stop-rtc-loop-chan {:stop true}
-                       :priority true)]
-                 (cond
-                   continue
-                   (recur (make-push-client-ops-timeout-ch repo (not @*auto-push-client-ops?)))
-
-                   push-data-from-ws
-                   (let [r (<! (<push-data-from-ws-handler state repo conn date-formatter push-data-from-ws))]
-                     (when (= r ::need-pull-remote-data)
+            (loop [push-client-ops-ch
+                   (make-push-client-ops-timeout-ch repo (not @*auto-push-client-ops?))]
+              (let [{:keys [push-data-from-ws client-op-update stop continue]}
+                    (async/alt!
+                      toggle-auto-push-client-ops-ch {:continue true}
+                      force-push-client-ops-ch {:client-op-update true}
+                      push-client-ops-ch ([v] (if (and @*auto-push-client-ops? (true? v))
+                                                {:client-op-update true}
+                                                {:continue true}))
+                      push-data-from-ws-ch ([v] {:push-data-from-ws v})
+                      stop-rtc-loop-chan {:stop true}
+                      :priority true)]
+                (cond
+                  continue
+                  (recur (make-push-client-ops-timeout-ch repo (not @*auto-push-client-ops?)))
+
+                  push-data-from-ws
+                  (let [r (<! (<push-data-from-ws-handler state repo conn date-formatter push-data-from-ws))]
+                    (when (= r ::need-pull-remote-data)
                        ;; trigger a force push, which can pull remote-diff-data from local-t to remote-t
-                       (async/put! force-push-client-ops-ch true))
-                     (recur (make-push-client-ops-timeout-ch repo (not @*auto-push-client-ops?))))
+                      (async/put! force-push-client-ops-ch true))
+                    (recur (make-push-client-ops-timeout-ch repo (not @*auto-push-client-ops?))))
 
-                   client-op-update
+                  client-op-update
                    ;; FIXME: access token expired
-                   (let [_ (<? (<client-op-update-handler state token))]
-                     (recur (make-push-client-ops-timeout-ch repo (not @*auto-push-client-ops?))))
+                  (let [_ (<? (<client-op-update-handler state token))]
+                    (recur (make-push-client-ops-timeout-ch repo (not @*auto-push-client-ops?))))
 
-                   stop
-                   (stop-rtc-helper state)
+                  stop
+                  (stop-rtc-helper state)
 
-                   :else
-                   nil)))))
+                  :else
+                  nil)))))
           (async/unsub data-from-ws-pub "push-updates" push-data-from-ws-ch)
+          :stop-rtc-loop
           (catch :default e
             (case (:type (ex-data e))
-              ::break-rtc-loop (prn :break-rtc-loop)
+              ::break-rtc-loop
+              (do (prn :break-rtc-loop)
+                  :break-rtc-loop)
               ;; else
               (prn ::unknown-ex e))))))))
 
@@ -1189,9 +1201,10 @@
               _ (reset! asset-sync/*asset-sync-state state-for-asset-sync)
               config (worker-state/get-config repo)
               c1 (<loop-for-rtc state graph-uuid repo conn (common-config/get-date-formatter config))
-              c2 (asset-sync/<loop-for-assets-sync state-for-asset-sync graph-uuid repo conn)]
-          (<! c1)
-          (<! c2)))
+              c2 (asset-sync/<loop-for-assets-sync state-for-asset-sync graph-uuid repo conn)
+              rtc-loop-result (<! c1)
+              _ (<! c2)]
+          (str rtc-loop-result)))
       (worker-util/post-message :notification
                                 [[:div
                                   [:p "RTC is not supported for this graph"]]