From 560ce3ca4f921949aa79f92bb5313787d50db7dd Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Thu, 26 Feb 2026 12:12:54 +0800 Subject: [PATCH] enhance: sync startup latency 1. Removes startup dependency on remote-graphs fetch for initial sync start. 2. Removes unnecessary restart churn. 3. Shaves trigger scheduling delay. --- .../frontend/handler/db_based/rtc_flows.cljs | 2 +- src/main/frontend/handler/db_based/sync.cljs | 23 +++++++++++- src/main/frontend/handler/user.cljs | 37 +++++++++++++++++-- src/main/frontend/worker/sync.cljs | 34 +++++++++++++---- src/main/mobile/components/header.cljs | 4 +- 5 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/main/frontend/handler/db_based/rtc_flows.cljs b/src/main/frontend/handler/db_based/rtc_flows.cljs index 852cc7685d..56e5e30f44 100644 --- a/src/main/frontend/handler/db_based/rtc_flows.cljs +++ b/src/main/frontend/handler/db_based/rtc_flows.cljs @@ -153,4 +153,4 @@ conditions: (apply c.m/mix) (m/latest vector flows/current-login-user-flow) (m/eduction (keep (fn [[current-user trigger-event]] (when current-user trigger-event)))) - (c.m/debounce 200))) + (c.m/debounce 50))) diff --git a/src/main/frontend/handler/db_based/sync.cljs b/src/main/frontend/handler/db_based/sync.cljs index 63b5331f72..4dc4873794 100644 --- a/src/main/frontend/handler/db_based/sync.cljs +++ b/src/main/frontend/handler/db_based/sync.cljs @@ -185,6 +185,23 @@ [repo] (some #(= repo (:url %)) (state/get-rtc-graphs))) +(defn- graph-has-local-rtc-id? + [repo] + (boolean (some-> (db/get-db repo) + ldb/get-graph-rtc-uuid))) + +(defn- remote-graphs-unknown? + [] + (not= false (:rtc/loading-graphs? @state/state))) + +(defn- should-start-rtc? + [repo] + (or (graph-in-remote-list? repo) + ;; During startup, remote graph list might not be fetched yet. + ;; If local DB already has graph UUID, start optimistically to reduce cold-start latency. + (and (remote-graphs-unknown?) + (graph-has-local-rtc-id? repo)))) + (defn- normalize-graph-e2ee? [graph-e2ee?] (if (nil? graph-e2ee?) @@ -193,12 +210,14 @@ (defn clj :keywordize-keys true) (update :cognito:username decode-username))) +(defn- parse-jwt-safe + [jwt] + (try + (parse-jwt jwt) + (catch :default _ + nil))) + (defn- expired? [parsed-jwt] (some-> (* 1000 (:exp parsed-jwt)) @@ -191,12 +198,34 @@ "Refresh id-token&access-token, pull latest repos, returns nil when tokens are not available." [] (println "restore-tokens-from-localstorage") - (let [refresh-token (js/localStorage.getItem "refresh-token")] - (when refresh-token + (let [refresh-token (js/localStorage.getItem "refresh-token") + id-token (js/localStorage.getItem "id-token") + access-token (js/localStorage.getItem "access-token") + restored-from-cache? + (boolean + (when (and (string? refresh-token) (not (string/blank? refresh-token)) + (string? id-token) (not (string/blank? id-token)) + (string? access-token) (not (string/blank? access-token))) + (when-let [parsed (parse-jwt-safe id-token)] + (when-not (expired? parsed) + (set-tokens! id-token access-token refresh-token) + true)))) + should-refresh? + (and (string? refresh-token) + (not (string/blank? refresh-token)) + (or (not restored-from-cache?) + (some-> (state/get-auth-id-token) + parse-jwt-safe + almost-expired?)))] + (when restored-from-cache? + ;; Publish login event immediately so sync can start without waiting token refresh request. + (state/pub-event! [:user/fetch-info-and-graphs])) + (when should-refresh? (go ( (:ws-state client) deref) + ws-ready-state (when ws (ready-state ws))] + (or (= :open ws-state) + (contains? #{0 1} ws-ready-state))))) + (defn start! [repo] - (p/do! - (stop!) - (let [base (ws-base-url) - graph-id (get-graph-id repo)] - (if (and (string? base) (seq base) (seq graph-id)) + (let [base (ws-base-url) + graph-id (get-graph-id repo) + current @worker-state/*db-sync-client] + (cond + (not (and (string? base) (seq base) (seq graph-id))) + (do + (log/info :db-sync/start-skipped {:repo repo :graph-id graph-id :base base}) + (p/resolved nil)) + + (active-client-for? current repo graph-id) + (do + (broadcast-rtc-state! current) + (p/resolved nil)) + + :else + (p/do! + (stop!) (let [client (ensure-client-state! repo) url (format-ws-url base graph-id) _ (ensure-client-graph-uuid! repo graph-id) connected (assoc client :graph-id graph-id) connected (connect! repo connected url)] (reset! worker-state/*db-sync-client connected) - (p/resolved nil)) - (do - (log/info :db-sync/start-skipped {:repo repo :graph-id graph-id :base base}) (p/resolved nil)))))) (defn enqueue-local-tx! diff --git a/src/main/mobile/components/header.cljs b/src/main/mobile/components/header.cljs index 6075295a1c..f4fb8cb141 100644 --- a/src/main/mobile/components/header.cljs +++ b/src/main/mobile/components/header.cljs @@ -152,7 +152,7 @@ (reset! native-top-bar-listener? true))) (defn- configure-native-top-bar! - [repo {:keys [tab title route-name route-view sync-color favorited? show-sync?]}] + [{:keys [tab title route-name route-view sync-color favorited? show-sync?]}] (when (and (mobile-util/native-platform?) mobile-util/native-top-bar) (let [hidden? (and (mobile-util/native-ios?) (= tab "search")) @@ -247,7 +247,6 @@ title (or (:block/title block) fallback-title) f (fn [favorited?] (configure-native-top-bar! - current-repo {:tab tab :title title :route-name route-name @@ -277,7 +276,6 @@ title (:block/title block) f (fn [favorited?] (configure-native-top-bar! - current-repo {:tab tab :title title :route-name route-name