Ver código fonte

wip: transact to worker directly

Previously, the transactions will go though main thread db -> worker
db, this commit changes it to worker db first and then send the
updates to the main thread db.

This change does introduce some bugs because all the db transactions
are async now.
Tienson Qin 2 anos atrás
pai
commit
5fd91035df

+ 7 - 2
deps/db/src/logseq/db.cljs

@@ -48,18 +48,23 @@
     {:block/page [:db/id :block/name :block/original-name :block/journal-day]}
     {:block/page [:db/id :block/name :block/original-name :block/journal-day]}
     {:block/_parent ...}])
     {:block/_parent ...}])
 
 
+(defonce *transact-fn (atom nil))
+(defn register-transact-fn!
+  [f]
+  (when f (reset! *transact-fn f)))
 
 
 (defn transact!
 (defn transact!
   ([conn tx-data]
   ([conn tx-data]
    (transact! conn tx-data nil))
    (transact! conn tx-data nil))
   ([conn tx-data tx-meta]
   ([conn tx-data tx-meta]
    (let [tx-data (common-util/fast-remove-nils tx-data)]
    (let [tx-data (common-util/fast-remove-nils tx-data)]
-    (when (seq tx-data)
+     (when (seq tx-data)
 
 
       ;; (prn :debug :transact)
       ;; (prn :debug :transact)
       ;; (cljs.pprint/pprint tx-data)
       ;; (cljs.pprint/pprint tx-data)
 
 
-      (d/transact! conn tx-data tx-meta)))))
+       (let [f (or @*transact-fn d/transact!)]
+         (f conn tx-data tx-meta))))))
 
 
 (defn create-default-pages!
 (defn create-default-pages!
   "Creates default pages if one of the default pages does not exist. This
   "Creates default pages if one of the default pages does not exist. This

+ 0 - 1
src/main/frontend/db/conn.cljs

@@ -10,7 +10,6 @@
             [logseq.db :as ldb]
             [logseq.db :as ldb]
             [logseq.db.frontend.schema :as db-schema]
             [logseq.db.frontend.schema :as db-schema]
             [logseq.common.util :as common-util]
             [logseq.common.util :as common-util]
-            [datascript.core :as d]
             [logseq.db.sqlite.util :as sqlite-util]))
             [logseq.db.sqlite.util :as sqlite-util]))
 
 
 (defonce conns (atom {}))
 (defonce conns (atom {}))

+ 0 - 3
src/main/frontend/handler.cljs

@@ -46,9 +46,6 @@
             [frontend.persist-db.browser :as db-browser]
             [frontend.persist-db.browser :as db-browser]
             [frontend.persist-db :as persist-db]))
             [frontend.persist-db :as persist-db]))
 
 
-;; TODO: remove this after transact directly to worker db
-(reset! db-listener/*db-listener persist-db/transact-db->worker!)
-
 (defn- set-global-error-notification!
 (defn- set-global-error-notification!
   []
   []
   (when-not config/dev?
   (when-not config/dev?

+ 9 - 9
src/main/frontend/handler/editor.cljs

@@ -821,15 +821,15 @@
                              (delete-block-fn prev-block)
                              (delete-block-fn prev-block)
                              (save-block! repo block new-content {:editor/op :delete})
                              (save-block! repo block new-content {:editor/op :delete})
                              (outliner-save-block! {:db/id (:db/id block)
                              (outliner-save-block! {:db/id (:db/id block)
-                                                         :block/parent (:db/id (:block/parent prev-block))
-                                                         :block/left (or (:db/id (:block/left prev-block))
-                                                                         (:db/id (:block/parent prev-block)))})
+                                                    :block/parent (:db/id (:block/parent prev-block))
+                                                    :block/left (or (:db/id (:block/left prev-block))
+                                                                    (:db/id (:block/parent prev-block)))})
 
 
                              ;; block->right needs to point its `left` to block->left
                              ;; block->right needs to point its `left` to block->left
                              (when (and block-right (not= (:db/id (:block/parent prev-block))
                              (when (and block-right (not= (:db/id (:block/parent prev-block))
                                                           (:db/id (:block/parent block))))
                                                           (:db/id (:block/parent block))))
                                (outliner-save-block! {:db/id (:db/id block-right)
                                (outliner-save-block! {:db/id (:db/id block-right)
-                                                           :block/left (:db/id (:block/left block))}))
+                                                      :block/left (:db/id (:block/left block))}))
 
 
                              ;; update prev-block's children to point to the refed block
                              ;; update prev-block's children to point to the refed block
                              (when (or (:block/collapsed? prev-block)
                              (when (or (:block/collapsed? prev-block)
@@ -838,18 +838,18 @@
                                  (doseq [child children]
                                  (doseq [child children]
                                    (when-not (= (:db/id child) (:db/id block))
                                    (when-not (= (:db/id child) (:db/id block))
                                      (outliner-save-block! {:db/id (:db/id child)
                                      (outliner-save-block! {:db/id (:db/id child)
-                                                                 :block/parent (:db/id block)
-                                                                 :block/left (:db/id block)})))))
+                                                            :block/parent (:db/id block)
+                                                            :block/left (:db/id block)})))))
 
 
                              ;; parent will be removed
                              ;; parent will be removed
                              (when (= (:db/id prev-block) (:db/id (:block/parent block)))
                              (when (= (:db/id prev-block) (:db/id (:block/parent block)))
                                (when-let [parent-right (outliner-core/get-right-sibling (db/get-db) (:db/id prev-block))]
                                (when-let [parent-right (outliner-core/get-right-sibling (db/get-db) (:db/id prev-block))]
                                  (outliner-save-block! {:db/id (:db/id parent-right)
                                  (outliner-save-block! {:db/id (:db/id parent-right)
-                                                             :block/left (:db/id block)})))
+                                                        :block/left (:db/id block)})))
 
 
                              (when db-based?
                              (when db-based?
                                (outliner-save-block! {:db/id (:db/id block)
                                (outliner-save-block! {:db/id (:db/id block)
-                                                           :block/properties new-properties}))
+                                                      :block/properties new-properties}))
                              (when pos
                              (when pos
                                (util/schedule
                                (util/schedule
                                 (fn []
                                 (fn []
@@ -861,7 +861,7 @@
                              (save-block! repo prev-block new-content {:editor/op :delete})
                              (save-block! repo prev-block new-content {:editor/op :delete})
                              (when db-based?
                              (when db-based?
                                (outliner-save-block! {:db/id (:db/id prev-block)
                                (outliner-save-block! {:db/id (:db/id prev-block)
-                                                           :block/properties new-properties})))))
+                                                      :block/properties new-properties})))))
 
 
                        :else
                        :else
                        (delete-block-fn block))))))))))))
                        (delete-block-fn block))))))))))))

+ 5 - 2
src/main/frontend/handler/editor/lifecycle.cljs

@@ -4,7 +4,8 @@
             [frontend.state :as state]
             [frontend.state :as state]
             [frontend.util :as util]
             [frontend.util :as util]
             [frontend.util.cursor :as cursor]
             [frontend.util.cursor :as cursor]
-            [goog.dom :as gdom]))
+            [goog.dom :as gdom]
+            [frontend.db :as db]))
 
 
 (defn did-mount!
 (defn did-mount!
   [state]
   [state]
@@ -43,7 +44,9 @@
            (not (contains? #{:insert :indent-outdent :auto-save :undo :redo :delete} (state/get-editor-op)))
            (not (contains? #{:insert :indent-outdent :auto-save :undo :redo :delete} (state/get-editor-op)))
            ;; Don't trigger auto-save if the latest op is undo or redo
            ;; Don't trigger auto-save if the latest op is undo or redo
            (not (contains? #{:undo :redo :paste-blocks} (state/get-editor-latest-op))))
            (not (contains? #{:undo :redo :paste-blocks} (state/get-editor-latest-op))))
-      (editor-handler/save-block! (get-state) value)))
+      (let [state (get-state)]
+        (when (db/entity [:block/uuid (:block/uuid (:block state))]) ; block still exists
+          (editor-handler/save-block! state value)))))
   state)
   state)
 
 
 (def lifecycle
 (def lifecycle

+ 33 - 25
src/main/frontend/modules/outliner/pipeline.cljs

@@ -7,32 +7,35 @@
             [frontend.state :as state]
             [frontend.state :as state]
             [frontend.util.cursor :as cursor]
             [frontend.util.cursor :as cursor]
             [frontend.util.drawer :as drawer]
             [frontend.util.drawer :as drawer]
-            [frontend.modules.editor.undo-redo :as undo-redo]))
+            [frontend.modules.editor.undo-redo :as undo-redo]
+            [datascript.core :as d]))
 
 
 (defn- reset-editing-block-content!
 (defn- reset-editing-block-content!
   [tx-data tx-meta]
   [tx-data tx-meta]
-  (let [repo (state/get-current-repo)
-        db? (config/db-based-graph? repo)]
-    (when-not (or (:undo? tx-meta) (:redo? tx-meta))
-      (when-let [edit-block (state/get-edit-block)]
-        (when-let [last-datom (-> (filter (fn [datom]
-                                            (and (= :block/content (:a datom))
-                                                 (= (:e datom) (:db/id edit-block)))) tx-data)
-                                  last)]
-          (when-let [input (state/get-input)]
-            (when (:added last-datom)
-              (let [entity (db/entity (:e last-datom))
-                    db-content (:block/content entity)
-                    content (if db? db-content
-                                (->> db-content
-                                     (property-util/remove-built-in-properties (or (:block/format entity) :markdown))
-                                     drawer/remove-logbook))
-                    pos (cursor/pos input)
-                    pos (when pos (if (zero? pos) (count content) 0))]
-                (when (not= (string/trim content)
-                            (string/trim (.-value input)))
-                  (state/set-edit-content! input content))
-                (when pos (cursor/move-cursor-to input pos))))))))))
+  ;; FIXME:
+  ;; (let [repo (state/get-current-repo)
+  ;;       db? (config/db-based-graph? repo)]
+  ;;   (when-not (or (:undo? tx-meta) (:redo? tx-meta))
+  ;;     (when-let [edit-block (state/get-edit-block)]
+  ;;       (when-let [last-datom (-> (filter (fn [datom]
+  ;;                                           (and (= :block/content (:a datom))
+  ;;                                                (= (:e datom) (:db/id edit-block)))) tx-data)
+  ;;                                 last)]
+  ;;         (when-let [input (state/get-input)]
+  ;;           (when (:added last-datom)
+  ;;             (let [entity (db/entity (:e last-datom))
+  ;;                   db-content (:block/content entity)
+  ;;                   content (if db? db-content
+  ;;                               (->> db-content
+  ;;                                    (property-util/remove-built-in-properties (or (:block/format entity) :markdown))
+  ;;                                    drawer/remove-logbook))
+  ;;                   pos (cursor/pos input)
+  ;;                   pos (when pos (if (zero? pos) (count content) 0))]
+  ;;               (when (not= (string/trim content)
+  ;;                           (string/trim (.-value input)))
+  ;;                 (state/set-edit-content! input content))
+  ;;               (when pos (cursor/move-cursor-to input pos)))))))))
+  )
 
 
 (defn store-undo-data!
 (defn store-undo-data!
   [{:keys [tx-meta] :as opts}]
   [{:keys [tx-meta] :as opts}]
@@ -47,12 +50,16 @@
 
 
 (defn invoke-hooks
 (defn invoke-hooks
   [{:keys [tx-meta tx-data deleted-block-uuids affected-keys blocks] :as opts}]
   [{:keys [tx-meta tx-data deleted-block-uuids affected-keys blocks] :as opts}]
-  (store-undo-data! opts)
-  (let [{:keys [from-disk? new-graph?]} tx-meta
+  (let [{:keys [from-disk? new-graph? local-tx?]} tx-meta
         repo (state/get-current-repo)
         repo (state/get-current-repo)
         tx-report {:tx-meta tx-meta
         tx-report {:tx-meta tx-meta
                    :tx-data tx-data}]
                    :tx-data tx-data}]
 
 
+    (when local-tx? (store-undo-data! opts))
+
+    (let [conn (db/get-db repo false)]
+      (d/transact! conn tx-data tx-meta))
+
     (when (= (:outliner-op tx-meta) :delete-page)
     (when (= (:outliner-op tx-meta) :delete-page)
       (state/pub-event! [:page/deleted repo (:deleted-page tx-meta) (:file-path tx-meta)]))
       (state/pub-event! [:page/deleted repo (:deleted-page tx-meta) (:file-path tx-meta)]))
 
 
@@ -65,6 +72,7 @@
         (catch :default e
         (catch :default e
           (prn :reset-editing-block-content)
           (prn :reset-editing-block-content)
           (js/console.error e)))
           (js/console.error e)))
+
       (let [importing? (:graph/importing @state/state)]
       (let [importing? (:graph/importing @state/state)]
         (when-not importing?
         (when-not importing?
           (react/refresh! repo tx-report affected-keys))
           (react/refresh! repo tx-report affected-keys))

+ 0 - 12
src/main/frontend/persist_db.cljs

@@ -18,9 +18,6 @@
  (defn <unsafe-delete [repo]
  (defn <unsafe-delete [repo]
    (protocol/<unsafe-delete (get-impl) repo))
    (protocol/<unsafe-delete (get-impl) repo))
 
 
-(defn <transact-data [repo tx-data tx-meta]
-  (protocol/<transact-data (get-impl) repo tx-data tx-meta))
-
 (defn <export-db
 (defn <export-db
   [repo opts]
   [repo opts]
   (protocol/<export-db (get-impl) repo opts))
   (protocol/<export-db (get-impl) repo opts))
@@ -44,12 +41,3 @@
   (p/let [_ (protocol/<new (get-impl) repo)
   (p/let [_ (protocol/<new (get-impl) repo)
           _ (<export-db repo {})]
           _ (<export-db repo {})]
     (ipc/ipc :db-open repo)))
     (ipc/ipc :db-open repo)))
-
-(defn <release-access-handles
-  [repo]
-  (protocol/<release-access-handles (get-impl) repo))
-
-(defn transact-db->worker!
-  [repo tx-report]
-  (when-not (:pipeline-replace? (:tx-meta tx-report))
-    (<transact-data repo (:tx-data tx-report) (:tx-meta tx-report))))

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

@@ -11,7 +11,8 @@
             [cljs-bean.core :as bean]
             [cljs-bean.core :as bean]
             [frontend.state :as state]
             [frontend.state :as state]
             [electron.ipc :as ipc]
             [electron.ipc :as ipc]
-            [frontend.handler.worker :as worker-handler]))
+            [frontend.handler.worker :as worker-handler]
+            [logseq.db :as ldb]))
 
 
 (defonce *worker (atom nil))
 (defonce *worker (atom nil))
 
 
@@ -36,6 +37,25 @@
                  (when (seq new-state)
                  (when (seq new-state)
                    (.sync-app-state worker (pr-str new-state)))))))
                    (.sync-app-state worker (pr-str new-state)))))))
 
 
+(defn- transact!
+  [^js worker repo tx-data tx-meta]
+  (let [tx-meta' (pr-str tx-meta)
+        tx-data' (pr-str tx-data)
+        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)
+                 :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)}]
+    (if worker
+      (.transact worker repo tx-data' tx-meta'
+                 (pr-str context))
+      (notification/show! "Latest change was not saved! Please restart the application." :error))))
+
 (defn start-db-worker!
 (defn start-db-worker!
   []
   []
   (when-not (or config/publishing? util/node-test?)
   (when-not (or config/publishing? util/node-test?)
@@ -50,9 +70,16 @@
                   _ (.sync-app-state wrapped-worker
                   _ (.sync-app-state wrapped-worker
                                      (pr-str
                                      (pr-str
                                       {:git/current-repo (state/get-current-repo)
                                       {:git/current-repo (state/get-current-repo)
-                                       :config (:config @state/state)}))]
-            (sync-app-state! wrapped-worker)
-            (ask-persist-permission!))
+                                       :config (:config @state/state)}))
+                  _ (sync-app-state! wrapped-worker)
+                  _ (ask-persist-permission!)]
+            (ldb/register-transact-fn!
+             (fn worker-transact!
+               [_conn tx-data tx-meta]
+               (prn :debug :transact :tx-meta tx-meta :tx-data tx-data)
+               (transact! wrapped-worker (state/get-current-repo) tx-data
+                 ;; not from remote(rtc)
+                 (assoc tx-meta :local-tx? true)))))
           (p/catch (fn [error]
           (p/catch (fn [error]
                      (prn :debug "Can't init SQLite wasm")
                      (prn :debug "Can't init SQLite wasm")
                      (js/console.error error)
                      (js/console.error error)
@@ -97,26 +124,6 @@
     (when-let [^js sqlite @*worker]
     (when-let [^js sqlite @*worker]
       (.releaseAccessHandles sqlite repo)))
       (.releaseAccessHandles sqlite repo)))
 
 
-  (<transact-data [_this repo tx-data tx-meta]
-    (let [^js sqlite @*worker]
-      (when-not (:pipeline-replace? tx-meta) ; from db worker
-        (let [tx-meta' (pr-str tx-meta)
-              tx-data' (pr-str tx-data)
-              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)
-                       :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)}]
-          (if sqlite
-            (.transact sqlite repo tx-data' tx-meta'
-                       (pr-str context))
-            (notification/show! "Latest change was not saved! Please restart the application." :error))))))
-
   (<fetch-initial-data [_this repo _opts]
   (<fetch-initial-data [_this repo _opts]
     (when-let [^js sqlite @*worker]
     (when-let [^js sqlite @*worker]
       (-> (p/let [db-exists? (.dbExists sqlite repo)
       (-> (p/let [db-exists? (.dbExists sqlite repo)

+ 0 - 1
src/main/frontend/persist_db/protocol.cljs

@@ -6,7 +6,6 @@
   (<new [this repo] "Create or open a graph")
   (<new [this repo] "Create or open a graph")
   (<unsafe-delete [this repo] "Delete graph and its vfs")
   (<unsafe-delete [this repo] "Delete graph and its vfs")
   (<release-access-handles [this repo] "Release access file handles")
   (<release-access-handles [this repo] "Release access file handles")
-  (<transact-data [this repo tx-data tx-meta] "Transact data to db")
   (<fetch-initial-data [this repo opts] "Fetch Initial data")
   (<fetch-initial-data [this repo opts] "Fetch Initial data")
   (<export-db [this repo opts] "Save or get SQLite db")
   (<export-db [this repo opts] "Save or get SQLite db")
   (<import-db [this repo data] "Import SQLite db"))
   (<import-db [this repo data] "Import SQLite db"))

+ 28 - 28
src/main/frontend/worker/pipeline.cljs

@@ -69,15 +69,14 @@
 
 
 (defn invoke-hooks
 (defn invoke-hooks
   [repo conn tx-report context]
   [repo conn tx-report context]
-  (let [tx-meta (:tx-meta tx-report)
-        {:keys [from-disk? new-graph?]} tx-meta
-        fix-tx-data (validate-and-fix-db! repo conn tx-report context)]
-    (if (or from-disk? new-graph?)
-      {:tx-report tx-report}
-      (let [{:keys [pages blocks]} (ds-report/get-blocks-and-pages tx-report)
-            deleted-block-uuids (set (outliner-pipeline/filter-deleted-blocks (:tx-data tx-report)))
-            replace-tx (when-not (:pipeline-replace? tx-meta)
-                         (concat
+  (when-not (:pipeline-replace? (:tx-meta tx-report))
+    (let [tx-meta (:tx-meta tx-report)
+          {:keys [from-disk? new-graph?]} tx-meta]
+      (if (or from-disk? new-graph?)
+        {:tx-report tx-report}
+        (let [{:keys [pages blocks]} (ds-report/get-blocks-and-pages tx-report)
+              deleted-block-uuids (set (outliner-pipeline/filter-deleted-blocks (:tx-data tx-report)))
+              replace-tx (concat
                           ;; block path refs
                           ;; block path refs
                           (set (compute-block-path-refs-tx tx-report blocks))
                           (set (compute-block-path-refs-tx tx-report blocks))
 
 
@@ -93,22 +92,23 @@
                                     (when-let [db-id (:db/id b)]
                                     (when-let [db-id (:db/id b)]
                                       {:db/id db-id
                                       {:db/id db-id
                                        :block/tx-id tx-id})) updated-blocks)
                                        :block/tx-id tx-id})) updated-blocks)
-                             (remove nil?)))))
-            tx-report' (or
-                        (when (seq replace-tx)
-                          (ldb/transact! conn replace-tx {:replace? true
-                                                          :pipeline-replace? true}))
-                        tx-report)
-            full-tx-data (concat (:tx-data tx-report) fix-tx-data (:tx-data tx-report'))
-            final-tx-report (assoc tx-report' :tx-data full-tx-data)
-            affected-query-keys (when-not (:importing? context)
-                                  (worker-react/get-affected-queries-keys final-tx-report))]
-        (doseq [page pages]
-          (file/sync-to-file repo (:db/id page) tx-meta))
-        {:tx-report final-tx-report
-         :replace-tx-data (:tx-data tx-report')
-         :replace-tx-meta (:tx-meta tx-report')
-         :affected-keys affected-query-keys
-         :deleted-block-uuids deleted-block-uuids
-         :pages pages
-         :blocks blocks}))))
+                             (remove nil?))))
+              tx-report' (or
+                          (when (seq replace-tx)
+                            (ldb/transact! conn replace-tx {:replace? true
+                                                            :pipeline-replace? true}))
+                          tx-report)
+              fix-tx-data (validate-and-fix-db! repo conn tx-report context)
+              full-tx-data (concat (:tx-data tx-report) fix-tx-data (:tx-data tx-report'))
+              final-tx-report (assoc tx-report' :tx-data full-tx-data)
+              affected-query-keys (when-not (:importing? context)
+                                    (worker-react/get-affected-queries-keys final-tx-report))]
+          (doseq [page pages]
+            (file/sync-to-file repo (:db/id page) tx-meta))
+          {:tx-report final-tx-report
+           :replace-tx-data (:tx-data tx-report')
+           :replace-tx-meta (:tx-meta tx-report')
+           :affected-keys affected-query-keys
+           :deleted-block-uuids deleted-block-uuids
+           :pages pages
+           :blocks blocks})))))

+ 1 - 1
src/main/frontend/worker/rtc/core.cljs

@@ -489,7 +489,7 @@
       (swap! *depend-on-block-uuid-set conj target-uuid))))
       (swap! *depend-on-block-uuid-set conj target-uuid))))
 
 
 (defmethod local-block-ops->remote-ops-aux :update-op
 (defmethod local-block-ops->remote-ops-aux :update-op
-  [_ & {:keys [repo conn block update-op left-uuid parent-uuid *remote-ops]}]
+  [_ & {:keys [conn block update-op left-uuid parent-uuid *remote-ops]}]
   (let [block-uuid (:block/uuid block)
   (let [block-uuid (:block/uuid block)
         attr-map (:updated-attrs (second update-op))
         attr-map (:updated-attrs (second update-op))
         attr-alias-map (when (contains? attr-map :alias)
         attr-alias-map (when (contains? attr-map :alias)