فهرست منبع

refactor: ensure db tx from UI goes through apply-outliner-ops

Removed thread-api/transact and combine ui state and context.
Tienson Qin 9 ماه پیش
والد
کامیت
6fc010f844

+ 1 - 2
src/main/frontend/components/imports.cljs

@@ -18,7 +18,6 @@
             [frontend.handler.repo :as repo-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.ui :as ui-handler]
-            [frontend.persist-db.browser :as db-browser]
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
@@ -382,7 +381,7 @@
                                   (let [tx-reports
                                         (gp-exporter/add-file-to-db-graph conn (:file/path m) (:file/content m) opts)]
                                     (doseq [tx-report tx-reports]
-                                      (db-browser/transact! repo (:tx-data tx-report) (:tx-meta tx-report)))))}
+                                      (db/transact! repo (:tx-data tx-report) (:tx-meta tx-report)))))}
           {:keys [files import-state]} (gp-exporter/export-file-graph repo db-conn config-file *files options)]
     (log/info :import-file-graph {:msg (str "Import finished in " (/ (t/in-millis (t/interval start-time (t/now))) 1000) " seconds")})
     (state/set-state! :graph/importing nil)

+ 1 - 17
src/main/frontend/handler/events.cljs

@@ -163,21 +163,6 @@
   (p/let [_ (page-handler/create-today-journal!)]
     (ui-handler/re-render-root!)))
 
-(defmethod handle :graph/sync-context []
-  (let [context {:dev? config/dev?
-                 :node-test? util/node-test?
-                 :validate-db-options (:dev/validate-db-options (state/get-config))
-                 :importing? (:graph/importing @state/state)
-                 :date-formatter (state/get-date-formatter)
-                 :journal-file-name-format (or (state/get-journal-file-name-format)
-                                               date/default-journal-filename-formatter)
-                 :export-bullet-indentation (state/get-export-bullet-indentation)
-                 :preferred-format (state/get-preferred-format)
-                 :journals-directory (config/get-journals-directory)
-                 :whiteboards-directory (config/get-whiteboards-directory)
-                 :pages-directory (config/get-pages-directory)}]
-    (state/<invoke-db-worker :thread-api/set-context context)))
-
 ;; Hook on a graph is ready to be shown to the user.
 ;; It's different from :graph/restored, as :graph/restored is for window reloaded
 ;; FIXME: config may not be loaded when the graph is ready.
@@ -191,8 +176,7 @@
         (state/pub-event! [:graph/dir-gone dir]))))
   (let [db-based? (config/db-based-graph? repo)]
     (p/do!
-     (state/pub-event! [:graph/sync-context])
-    ;; re-render-root is async and delegated to rum, so we need to wait for main ui to refresh
+      ;; re-render-root is async and delegated to rum, so we need to wait for main ui to refresh
      (when (mobile-util/native-ios?)
        (js/setTimeout #(mobile/mobile-postinit) 1000))
     ;; FIXME: an ugly implementation for redirecting to page on new window is restored

+ 30 - 31
src/main/frontend/persist_db/browser.cljs

@@ -7,6 +7,7 @@
             [frontend.common.thread-api :as thread-api]
             [frontend.config :as config]
             [frontend.date :as date]
+            [frontend.db :as db]
             [frontend.db.transact :as db-transact]
             [frontend.handler.notification :as notification]
             [frontend.handler.worker :as worker-handler]
@@ -23,19 +24,37 @@
       (js/console.log "Storage will not be cleared unless from explicit user action")
       (js/console.warn "OPFS storage may be cleared by the browser under storage pressure."))))
 
+(defn- get-worker-state-context
+  [state]
+  (let [config (:config state)]
+    {:state (select-keys state [:git/current-repo config])
+     :context {:dev? config/dev?
+               :node-test? util/node-test?
+               :validate-db-options (:dev/validate-db-options config)
+               :importing? (:graph/importing state)
+               :date-formatter (or
+                                (:journal/page-title-format config)
+                                (state/get-date-formatter))
+               :journal-file-name-format (or (:journal/file-name-format config)
+                                             (state/get-journal-file-name-format)
+                                             date/default-journal-filename-formatter)
+               :export-bullet-indentation (or
+                                           (:export/bullet-indentation config)
+                                           (state/get-export-bullet-indentation))
+               :preferred-format (state/get-preferred-format)
+               :journals-directory (config/get-journals-directory)
+               :whiteboards-directory (config/get-whiteboards-directory)
+               :pages-directory (config/get-pages-directory)}}))
+
 (defn- sync-app-state!
   []
   (add-watch state/state
              :sync-worker-state
              (fn [_ _ prev current]
-               (let [new-state (cond-> {}
-                                 (not= (:git/current-repo prev)
-                                       (:git/current-repo current))
-                                 (assoc :git/current-repo (:git/current-repo current))
-                                 (not= (:config prev) (:config current))
-                                 (assoc :config (:config current)))]
-                 (when (seq new-state)
-                   (state/<invoke-db-worker :thread-api/sync-app-state new-state))))))
+               (let [state1 (get-worker-state-context prev)
+                     state2 (get-worker-state-context current)]
+                 (when (not= state1 state2)
+                   (state/<invoke-db-worker :thread-api/sync-app-state state2))))))
 
 (defn get-route-data
   [route-match]
@@ -60,23 +79,6 @@
                                               (state/get-current-repo)
                                               {:old-state old-state :new-state new-state})))))))
 
-(defn transact!
-  [repo tx-data tx-meta]
-  (let [;; TODO: a better way to share those information with worker, maybe using the state watcher to notify the worker?
-        context {:dev? config/dev?
-                 :node-test? util/node-test?
-                 :validate-db-options (:dev/validate-db-options (state/get-config))
-                 :importing? (:graph/importing @state/state)
-                 :date-formatter (state/get-date-formatter)
-                 :journal-file-name-format (or (state/get-journal-file-name-format)
-                                               date/default-journal-filename-formatter)
-                 :export-bullet-indentation (state/get-export-bullet-indentation)
-                 :preferred-format (state/get-preferred-format)
-                 :journals-directory (config/get-journals-directory)
-                 :whiteboards-directory (config/get-whiteboards-directory)
-                 :pages-directory (config/get-pages-directory)}]
-    (state/<invoke-db-worker :thread-api/transact repo tx-data tx-meta context)))
-
 (defn start-db-worker!
   []
   (when-not util/node-test?
@@ -99,17 +101,14 @@
       (reset! state/*db-worker wrapped-worker)
       (-> (p/let [_ (state/<invoke-db-worker :thread-api/init config/RTC-WS-URL)
                   _ (js/console.debug (str "debug: init worker spent: " (- (util/time-ms) t1) "ms"))
-                  _ (state/<invoke-db-worker :thread-api/sync-app-state
-                                             {:git/current-repo (state/get-current-repo)
-                                              :config (:config @state/state)})
+                  _ (state/<invoke-db-worker :thread-api/sync-app-state (get-worker-state-context @state/state))
                   _ (sync-app-state!)
                   _ (sync-ui-state!)
-                  _ (ask-persist-permission!)
-                  _ (state/pub-event! [:graph/sync-context])]
+                  _ (ask-persist-permission!)]
             (ldb/register-transact-fn!
              (fn worker-transact!
                [repo tx-data tx-meta]
-               (db-transact/transact transact!
+               (db-transact/transact db/transact!
                                      (if (string? repo) repo (state/get-current-repo))
                                      tx-data
                                      tx-meta)))

+ 1 - 0
src/main/frontend/worker/db_listener.cljs

@@ -68,6 +68,7 @@
       (d/listen! conn ::listen-db-changes!
                  (fn listen-db-changes!-inner
                    [{:keys [tx-data _db-before _db-after tx-meta] :as tx-report}]
+                   (worker-state/set-db-latest-tx-time! repo)
                    (let [tx-meta (merge (batch-tx/get-batch-opts) tx-meta)
                          pipeline-replace? (:pipeline-replace? tx-meta)
                          in-batch-tx-mode? (:batch-tx/batch-tx-mode? tx-meta)]

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

@@ -34,7 +34,6 @@
             [logseq.common.config :as common-config]
             [logseq.common.util :as common-util]
             [logseq.db :as ldb]
-            [logseq.db.common.order :as db-order]
             [logseq.db.common.sqlite :as sqlite-common-db]
             [logseq.db.common.view :as db-view]
             [logseq.db.frontend.entity-plus :as entity-plus]
@@ -551,60 +550,11 @@
       (->> (ldb/get-block-parents @conn block-id {:depth (or depth 3)})
            (map (fn [b] (d/pull @conn '[*] (:db/id b))))))))
 
-(def-thread-api :thread-api/set-context
-  [context]
-  (when context (worker-state/update-context! context))
-  nil)
-
-(def-thread-api :thread-api/transact
-  [repo tx-data tx-meta context]
-  (when repo (worker-state/set-db-latest-tx-time! repo))
-  (when-let [conn (worker-state/get-datascript-conn repo)]
-    (try
-      (let [tx-data' (if (contains? #{:insert-blocks} (:outliner-op tx-meta))
-                       (map (fn [m]
-                              (if (and (map? m) (nil? (:block/order m)))
-                                (assoc m :block/order (db-order/gen-key nil))
-                                m)) tx-data)
-                       tx-data)
-            _ (when context (worker-state/set-context! context))
-            tx-meta' (cond-> tx-meta
-                       (and (not (:whiteboard/transact? tx-meta))
-                            (not (:rtc-download-graph? tx-meta))) ; delay writes to the disk
-                       (assoc :skip-store? true)
-
-                       true
-                       (dissoc :insert-blocks?))]
-        (when-not (and (:create-today-journal? tx-meta)
-                       (:today-journal-name tx-meta)
-                       (seq tx-data')
-                       (ldb/get-page @conn (:today-journal-name tx-meta))) ; today journal created already
-
-           ;; (prn :debug :transact :tx-data tx-data' :tx-meta tx-meta')
-
-          (worker-util/profile "Worker db transact"
-                               (ldb/transact! conn tx-data' tx-meta')))
-        nil)
-      (catch :default e
-        (prn :debug :error)
-        (js/console.error e)
-        (prn :debug :tx-data @conn tx-data)))))
-
 (def-thread-api :thread-api/get-initial-data
   [repo]
   (when-let [conn (worker-state/get-datascript-conn repo)]
     (sqlite-common-db/get-initial-data @conn)))
 
-(def-thread-api :thread-api/get-page-refs-count
-  [repo]
-  (when-let [conn (worker-state/get-datascript-conn repo)]
-    (sqlite-common-db/get-page->refs-count @conn)))
-
-(def-thread-api :thread-api/close-db
-  [repo]
-  (close-db! repo)
-  nil)
-
 (def-thread-api :thread-api/reset-db
   [repo db-transit]
   (reset-db! repo db-transit)
@@ -710,8 +660,9 @@
   nil)
 
 (def-thread-api :thread-api/sync-app-state
-  [new-state]
-  (worker-state/set-new-state! new-state)
+  [{:keys [state context]}]
+  (when state (worker-state/set-new-state! state))
+  (when context (worker-state/update-context! context))
   nil)
 
 (def-thread-api :thread-api/sync-ui-state

+ 2 - 0
src/main/frontend/worker/pipeline.cljs

@@ -255,6 +255,8 @@
                                     (when (:block/uuid (d/entity db-after db-id))
                                       {:db/id db-id
                                        :block/tx-id tx-id}))) updated-blocks))))
+          ;; Notice: ldb/transact! needs to be executed even if `replace-tx` is empty,
+          ;; to ensure that the underlying db storage is persisted
           tx-report' (ldb/transact! conn replace-tx {:pipeline-replace? true})
           _ (validate-db! repo conn tx-report* tx-meta context)
           full-tx-data (concat (:tx-data tx-report*)

+ 13 - 12
src/main/frontend/worker/rtc/full_upload_download_graph.cljs

@@ -381,18 +381,19 @@
          (p/do!
           ((@thread-api/*thread-apis :thread-api/create-or-open-db) repo {:close-other-db? false})
           ((@thread-api/*thread-apis :thread-api/export-db) repo)
-          ((@thread-api/*thread-apis :thread-api/transact)
-           repo init-tx-data
-           {:rtc-download-graph? true
-            :gen-undo-ops? false
-             ;; only transact db schema, skip validation to avoid warning
-            :frontend.worker.pipeline/skip-validate-db? true
-            :persist-op? false}
-           (worker-state/get-context))
-          ((@thread-api/*thread-apis :thread-api/transact)
-           repo tx-data {:rtc-download-graph? true
-                         :gen-undo-ops? false
-                         :persist-op? false} (worker-state/get-context))
+          (let [conn (worker-state/get-datascript-conn repo)]
+            (d/transact! conn
+                         init-tx-data
+                         {:rtc-download-graph? true
+                          :gen-undo-ops? false
+                          ;; only transact db schema, skip validation to avoid warning
+                          :frontend.worker.pipeline/skip-validate-db? true
+                          :persist-op? false})
+            (d/transact! conn
+                         tx-data
+                         {:rtc-download-graph? true
+                          :gen-undo-ops? false
+                          :persist-op? false}))
           (transact-remote-schema-version! repo)
           (transact-block-refs! repo))))
       (worker-util/post-message :add-repo {:repo repo}))))