mirror of
https://github.com/penpot/penpot.git
synced 2025-01-08 07:50:43 -05:00
✨ Reduce lock contention on uploading file object thumbnail
This commit is contained in:
parent
4dacba6836
commit
56ba32b66d
2 changed files with 44 additions and 49 deletions
|
@ -228,51 +228,52 @@
|
||||||
;; MUTATION COMMANDS
|
;; MUTATION COMMANDS
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;; MUTATION COMMAND: create-file-object-thumbnail
|
(def sql:get-file-object-thumbnail
|
||||||
|
"SELECT * FROM file_tagged_object_thumbnail
|
||||||
|
WHERE file_id = ? AND object_id = ? AND tag = ?
|
||||||
|
FOR UPDATE")
|
||||||
|
|
||||||
(defn- create-file-object-thumbnail!
|
(def sql:create-file-object-thumbnail
|
||||||
[{:keys [::db/conn ::sto/storage]} file-id object-id media tag]
|
"INSERT INTO file_tagged_object_thumbnail (file_id, object_id, tag, media_id)
|
||||||
|
VALUES (?, ?, ?, ?)
|
||||||
|
ON CONFLICT (file_id, object_id, tag)
|
||||||
|
DO UPDATE SET updated_at=?, media_id=?, deleted_at=null
|
||||||
|
RETURNING *")
|
||||||
|
|
||||||
(let [thumb (db/get* conn :file-tagged-object-thumbnail
|
(defn- persist-thumbnail!
|
||||||
{:file-id file-id
|
[storage media created-at]
|
||||||
:object-id object-id
|
(let [path (:path media)
|
||||||
:tag tag}
|
|
||||||
{::db/remove-deleted false
|
|
||||||
::sql/for-update true})
|
|
||||||
|
|
||||||
path (:path media)
|
|
||||||
mtype (:mtype media)
|
mtype (:mtype media)
|
||||||
hash (sto/calculate-hash path)
|
hash (sto/calculate-hash path)
|
||||||
data (-> (sto/content path)
|
data (-> (sto/content path)
|
||||||
(sto/wrap-with-hash hash))
|
(sto/wrap-with-hash hash))]
|
||||||
tnow (dt/now)
|
|
||||||
|
|
||||||
media (sto/put-object! storage
|
(sto/put-object! storage
|
||||||
{::sto/content data
|
{::sto/content data
|
||||||
::sto/deduplicate? true
|
::sto/deduplicate? true
|
||||||
::sto/touched-at tnow
|
::sto/touched-at created-at
|
||||||
:content-type mtype
|
:content-type mtype
|
||||||
:bucket "file-object-thumbnail"})]
|
:bucket "file-object-thumbnail"})))
|
||||||
|
|
||||||
(if (some? thumb)
|
|
||||||
(do
|
|
||||||
;; We mark the old media id as touched if it does not matches
|
(defn- create-file-object-thumbnail!
|
||||||
(when (not= (:id media) (:media-id thumb))
|
[{:keys [::sto/storage] :as cfg} file-id object-id media tag]
|
||||||
(sto/touch-object! storage (:media-id thumb)))
|
(let [tsnow (dt/now)
|
||||||
(db/update! conn :file-tagged-object-thumbnail
|
media (persist-thumbnail! storage media tsnow)
|
||||||
{:media-id (:id media)
|
[th1 th2] (db/tx-run! cfg (fn [{:keys [::db/conn]}]
|
||||||
:deleted-at nil
|
(let [th1 (db/exec-one! conn [sql:get-file-object-thumbnail file-id object-id tag])
|
||||||
:updated-at tnow}
|
th2 (db/exec-one! conn [sql:create-file-object-thumbnail
|
||||||
{:file-id file-id
|
file-id object-id tag (:id media)
|
||||||
:object-id object-id
|
tsnow (:id media)])]
|
||||||
:tag tag}))
|
[th1 th2])))]
|
||||||
(db/insert! conn :file-tagged-object-thumbnail
|
|
||||||
{:file-id file-id
|
(when (and (some? th1)
|
||||||
:object-id object-id
|
(not= (:media-id th1)
|
||||||
:created-at tnow
|
(:media-id th2)))
|
||||||
:updated-at tnow
|
(sto/touch-object! storage (:media-id th1)))
|
||||||
:tag tag
|
|
||||||
:media-id (:id media)}))))
|
th2))
|
||||||
|
|
||||||
(def ^:private
|
(def ^:private
|
||||||
schema:create-file-object-thumbnail
|
schema:create-file-object-thumbnail
|
||||||
|
@ -296,16 +297,10 @@
|
||||||
(media/validate-media-type! media)
|
(media/validate-media-type! media)
|
||||||
(media/validate-media-size! media)
|
(media/validate-media-size! media)
|
||||||
|
|
||||||
(db/tx-run! cfg
|
(db/run! cfg files/check-edition-permissions! profile-id file-id)
|
||||||
(fn [{:keys [::db/conn] :as cfg}]
|
|
||||||
(files/check-edition-permissions! conn profile-id file-id)
|
(let [cfg (update cfg ::sto/storage media/configure-assets-storage)]
|
||||||
(when-not (db/read-only? conn)
|
(create-file-object-thumbnail! cfg file-id object-id media (or tag "frame"))))
|
||||||
(let [cfg (-> cfg
|
|
||||||
(update ::sto/storage media/configure-assets-storage)
|
|
||||||
(assoc ::rtry/when rtry/conflict-exception?)
|
|
||||||
(assoc ::rtry/max-retries 5)
|
|
||||||
(assoc ::rtry/label "create-file-object-thumbnail"))]
|
|
||||||
(create-file-object-thumbnail! cfg file-id object-id media (or tag "frame")))))))
|
|
||||||
|
|
||||||
;; --- MUTATION COMMAND: delete-file-object-thumbnail
|
;; --- MUTATION COMMAND: delete-file-object-thumbnail
|
||||||
|
|
||||||
|
|
|
@ -1158,7 +1158,7 @@
|
||||||
;; check that the unknown frame thumbnail is deleted
|
;; check that the unknown frame thumbnail is deleted
|
||||||
(let [rows (th/db-query :file-tagged-object-thumbnail {:file-id (:id file)})]
|
(let [rows (th/db-query :file-tagged-object-thumbnail {:file-id (:id file)})]
|
||||||
(t/is (= 2 (count rows)))
|
(t/is (= 2 (count rows)))
|
||||||
(t/is (= 1 (count (remove (comp some? :deleted-at) rows)))))
|
(t/is (= 1 (count (remove :deleted-at rows)))))
|
||||||
|
|
||||||
(let [res (th/run-task! :objects-gc {:min-age 0})]
|
(let [res (th/run-task! :objects-gc {:min-age 0})]
|
||||||
(t/is (= 3 (:processed res))))
|
(t/is (= 3 (:processed res))))
|
||||||
|
|
Loading…
Reference in a new issue