refactor(db-worker,wip): remove asset related <invoke-main-thread (2)

This commit is contained in:
rcmerci
2026-04-03 20:51:12 +08:00
parent 30671bf4e1
commit 504f6fa3ce
8 changed files with 360 additions and 215 deletions

View File

@@ -1,23 +1,15 @@
(ns ^:no-doc frontend.handler.assets
(:require [cljs-http-missionary.client :as http]
[clojure.string :as string]
[frontend.common.crypt :as crypt]
[frontend.common.missionary :as c.m]
[frontend.common.thread-api :as thread-api :refer [def-thread-api]]
(:require [clojure.string :as string]
[frontend.config :as config]
[frontend.fs :as fs]
[frontend.state :as state]
[frontend.util :as util]
[lambdaisland.glogi :as log]
[logseq.common.config :as common-config]
[logseq.common.path :as path]
[logseq.common.util :as common-util]
[logseq.db :as ldb]
[logseq.db.frontend.asset :as db-asset]
[medley.core :as medley]
[missionary.core :as m]
[promesa.core :as p])
(:import [missionary Cancelled]))
[promesa.core :as p]))
(defn exceed-limit-size?
"Asset size no more than 100M"
@@ -216,28 +208,6 @@
(p/let [[repo-dir assets-dir] (ensure-assets-dir! (state/get-current-repo))]
(path/path-join repo-dir assets-dir filename)))
(defn <get-all-asset-file-paths
[repo]
(when-let [path (config/get-repo-assets-root repo)]
(p/catch (fs/readdir path {:path-only? true})
(constantly nil))))
(defn <read-asset
"Throw if asset not found"
[repo asset-block-id asset-type]
(let [repo-dir (config/get-repo-dir repo)
file-path (path/path-join common-config/local-assets-dir
(str asset-block-id "." asset-type))]
(fs/read-file-raw repo-dir file-path {})))
(defn <get-asset-file-metadata
[repo asset-block-id asset-type]
(-> (p/let [file (<read-asset repo asset-block-id asset-type)
blob (js/Blob. (array file) (clj->js {:type "image"}))
checksum (get-file-checksum blob)]
{:checksum checksum})
(p/catch (constantly nil))))
(defn- asset-transfer-in-progress?
[progress-entry]
(let [{:keys [loaded total]} progress-entry]
@@ -268,150 +238,3 @@
repo
(:block/uuid asset-block))
true)))
(defn <write-asset
[repo asset-block-id asset-type data]
(let [asset-block-id-str (str asset-block-id)
file-name (str asset-block-id-str "." asset-type)]
(p/do!
(fs/write-asset-file! repo file-name data)
(state/update-state!
:assets/asset-file-write-finish
(fn [m] (assoc-in m [repo asset-block-id-str] (common-util/time-ms)))))))
(comment
;; en/decrypt assets
(def repo (state/get-current-repo))
(p/let [aes-key (crypt/<generate-aes-key)
asset (<read-asset repo "6903201e-9573-4914-ae88-7d3f1d095d1f" "png")
encrypted-asset (crypt/<encrypt-uint8array aes-key asset)
decrypted-asset (crypt/<decrypt-uint8array aes-key encrypted-asset)]
(def asset asset)
(def xxxx encrypted-asset)
(prn :decrypted (.-length decrypted-asset)
:origin (.-length asset))))
(defn <unlink-asset
[repo asset-block-id asset-type]
(let [file-path (path/path-join (config/get-repo-dir repo)
common-config/local-assets-dir
(str asset-block-id "." asset-type))]
(p/catch (fs/unlink! repo file-path {}) (constantly nil))))
(defn new-task--rtc-upload-asset
[repo aes-key asset-block-uuid-str asset-type checksum put-url & {:keys [extra-headers]}]
(assert (and asset-type checksum))
(m/sp
(let [asset-file (try (c.m/<? (<read-asset repo asset-block-uuid-str asset-type))
(catch :default e
(log/info :read-asset e)
(throw (ex-info "read-asset failed" {:type :rtc.exception/read-asset-failed} e))))
asset-file (if aes-key
(->uint8 asset-file)
asset-file)
asset-file* (if (not aes-key)
asset-file
(ldb/write-transit-str
(c.m/<? (crypt/<encrypt-uint8array aes-key asset-file))))
*progress-flow (atom nil)
headers (merge extra-headers
{"x-amz-meta-checksum" checksum
"x-amz-meta-type" asset-type})
http-task (http/put put-url {:headers headers
:body asset-file*
:with-credentials? false
:*progress-flow *progress-flow})]
(c.m/run-task :upload-asset-progress
(m/reduce (fn [_ v]
(state/update-state!
:rtc/asset-upload-download-progress
(fn [m] (assoc-in m [repo asset-block-uuid-str] v))))
@*progress-flow)
:succ (constantly nil))
(let [{:keys [status] :as r} (m/? http-task)]
(when-not (http/unexceptional-status? status)
(throw (ex-info "upload-asset failed"
{:type :rtc.exception/upload-asset-failed :data (dissoc r :body)})))))))
(defn new-task--rtc-download-asset
[repo aes-key asset-block-uuid-str asset-type get-url & {:keys [extra-headers]}]
(m/sp
(let [*progress-flow (atom nil)
http-task (http/get get-url {:with-credentials? false
:response-type :array-buffer
:headers extra-headers
:*progress-flow *progress-flow})
progress-canceler
(c.m/run-task :download-asset-progress
(m/reduce (fn [_ v]
(state/update-state!
:rtc/asset-upload-download-progress
(fn [m] (assoc-in m [repo asset-block-uuid-str] v))))
@*progress-flow)
:succ (constantly nil))]
(try
(let [{:keys [status body] :as r} (m/? http-task)]
(if-not (http/unexceptional-status? status)
(throw (ex-info "download asset failed"
{:type :rtc.exception/download-asset-failed :data (dissoc r :body)}))
(let [asset-file
(if (not aes-key)
body
(try
(let [asset-file-untransited (ldb/read-transit-str (.decode (js/TextDecoder.) body))]
(c.m/<? (crypt/<decrypt-uint8array aes-key asset-file-untransited)))
(catch js/SyntaxError _
body)
(catch :default e
;; if decrypt failed, write origin-body
(if (= "decrypt-uint8array" (ex-message e))
body
(throw e)))))]
(c.m/<? (<write-asset repo asset-block-uuid-str asset-type asset-file))
nil)))
(catch Cancelled e
(progress-canceler)
(throw e))))))
(def-thread-api :thread-api/unlink-asset
[repo asset-block-id asset-type]
(<unlink-asset repo asset-block-id asset-type))
(def-thread-api :thread-api/get-all-asset-file-paths
[repo]
(<get-all-asset-file-paths repo))
(def-thread-api :thread-api/get-asset-file-metadata
[repo asset-block-id asset-type]
(<get-asset-file-metadata repo asset-block-id asset-type))
(def-thread-api :thread-api/rtc-upload-asset
[repo exported-aes-key asset-block-uuid-str asset-type checksum put-url & {:as opts}]
(m/sp
(let [aes-key (when exported-aes-key (c.m/<? (crypt/<import-aes-key exported-aes-key)))]
(m/? (new-task--rtc-upload-asset repo aes-key asset-block-uuid-str asset-type checksum put-url opts)))))
(def-thread-api :thread-api/rtc-download-asset
[repo exported-aes-key asset-block-uuid-str asset-type get-url & {:as opts}]
(m/sp
(let [aes-key (when exported-aes-key (c.m/<? (crypt/<import-aes-key exported-aes-key)))]
(m/? (new-task--rtc-download-asset repo aes-key asset-block-uuid-str asset-type get-url opts)))))
(comment
;; read asset
(p/let [repo "logseq_db_demo"
;; Existing asset block's id
asset-block-id-str "672c5a1d-8171-4259-9f35-470c3c67e37f"
asset-type "png"
data (<read-asset repo asset-block-id-str asset-type)]
(js/console.dir data))
;; write asset
(p/let [repo "logseq_db_demo"
;; Existing asset block's id
asset-block-id-str "672c5a1d-8171-4259-9f35-470c3c67e37f"
asset-type "png"
data (<read-asset repo asset-block-id-str asset-type)
new-asset-id (random-uuid)
result (<write-asset repo new-asset-id asset-type data)]
(js/console.dir result)))

View File

@@ -23,6 +23,18 @@
(let [state data]
(state/pub-event! [:rtc/sync-state state])))
(defmethod handle :rtc-asset-upload-download-progress [_ _worker {:keys [repo asset-id progress]}]
(when (and (seq repo) (seq asset-id) (map? progress))
(state/update-state!
:rtc/asset-upload-download-progress
(fn [m] (assoc-in m [repo asset-id] progress)))))
(defmethod handle :asset-file-write-finish [_ _worker {:keys [repo asset-id ts]}]
(when (and (seq repo) (seq asset-id))
(state/update-state!
:assets/asset-file-write-finish
(fn [m] (assoc-in m [repo asset-id] (or ts (.now js/Date)))))))
(defmethod handle :vector-search-sync-state [_ _worker data]
(state/pub-event! [:vector-search/sync-state data]))