mirror of
https://github.com/penpot/penpot.git
synced 2025-05-31 23:21:39 +02:00
♻️ Replace mount with integrant.
This commit is contained in:
parent
31d7aacec1
commit
9f12456456
76 changed files with 2403 additions and 2215 deletions
|
@ -11,16 +11,36 @@
|
|||
"Generic task for permanent deletion of objects."
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[integrant.core :as ig]
|
||||
[app.db :as db]
|
||||
[app.metrics :as mtx]
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.tools.logging :as log]))
|
||||
|
||||
(s/def ::type keyword?)
|
||||
(s/def ::id ::us/uuid)
|
||||
(declare handler)
|
||||
(declare handle-deletion)
|
||||
|
||||
(s/def ::props
|
||||
(s/keys :req-un [::id ::type]))
|
||||
(defmethod ig/pre-init-spec ::handler [_]
|
||||
(s/keys :req-un [::db/pool ::mtx/metrics]))
|
||||
|
||||
(defmethod ig/init-key ::handler
|
||||
[_ {:keys [metrics] :as cfg}]
|
||||
(let [handler #(handler cfg %)]
|
||||
(->> {:registry (:registry metrics)
|
||||
:type :summary
|
||||
:name "task_delete_object_timing"
|
||||
:help "delete object task timing"}
|
||||
(mtx/instrument handler))))
|
||||
|
||||
(s/def ::type ::us/keyword)
|
||||
(s/def ::id ::us/uuid)
|
||||
(s/def ::props (s/keys :req-un [::id ::type]))
|
||||
|
||||
(defn- handler
|
||||
[{:keys [pool]} {:keys [props] :as task}]
|
||||
(us/verify ::props props)
|
||||
(db/with-atomic [conn pool]
|
||||
(handle-deletion conn props)))
|
||||
|
||||
(defmulti handle-deletion (fn [_ props] (:type props)))
|
||||
|
||||
|
@ -28,17 +48,6 @@
|
|||
[_conn {:keys [type]}]
|
||||
(log/warn "no handler found for" type))
|
||||
|
||||
(defn handler
|
||||
[{:keys [props] :as task}]
|
||||
(us/verify ::props props)
|
||||
(db/with-atomic [conn db/pool]
|
||||
(handle-deletion conn props)))
|
||||
|
||||
(mtx/instrument-with-summary!
|
||||
{:var #'handler
|
||||
:id "tasks__delete_object"
|
||||
:help "Timing of remove-object task."})
|
||||
|
||||
(defmethod handle-deletion :file
|
||||
[conn {:keys [id] :as props}]
|
||||
(let [sql "delete from file where id=? and deleted_at is not null"]
|
||||
|
|
|
@ -14,7 +14,22 @@
|
|||
[app.db :as db]
|
||||
[app.metrics :as mtx]
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.tools.logging :as log]))
|
||||
[clojure.tools.logging :as log]
|
||||
[integrant.core :as ig]))
|
||||
|
||||
(declare handler)
|
||||
|
||||
(defmethod ig/pre-init-spec ::handler [_]
|
||||
(s/keys :req-un [::db/pool ::mtx/metrics]))
|
||||
|
||||
(defmethod ig/init-key ::handler
|
||||
[_ {:keys [metrics] :as cfg}]
|
||||
(let [handler #(handler cfg %)]
|
||||
(->> {:registry (:registry metrics)
|
||||
:type :summary
|
||||
:name "task_delete_profile_timing"
|
||||
:help "delete profile task timing"}
|
||||
(mtx/instrument handler))))
|
||||
|
||||
(declare delete-profile-data)
|
||||
(declare delete-teams)
|
||||
|
@ -26,10 +41,10 @@
|
|||
(s/keys :req-un [::profile-id]))
|
||||
|
||||
(defn handler
|
||||
[{:keys [props] :as task}]
|
||||
[{:keys [pool]} {:keys [props] :as task}]
|
||||
(us/verify ::props props)
|
||||
(db/with-atomic [conn db/pool]
|
||||
(let [id (:profile-id props)
|
||||
(db/with-atomic [conn pool]
|
||||
(let [id (:profile-id props)
|
||||
profile (db/get-by-id conn :profile id {:for-update true})]
|
||||
(if (or (:is-demo profile)
|
||||
(not (nil? (:deleted-at profile))))
|
||||
|
@ -37,11 +52,6 @@
|
|||
(log/warn "Profile " (:id profile)
|
||||
"does not match constraints for deletion")))))
|
||||
|
||||
(mtx/instrument-with-summary!
|
||||
{:var #'handler
|
||||
:id "tasks__delete_profile"
|
||||
:help "Timing of delete-profile task."})
|
||||
|
||||
(defn- delete-profile-data
|
||||
[conn profile-id]
|
||||
(log/info "Proceding to delete all data related to profile" profile-id)
|
||||
|
|
|
@ -13,20 +13,49 @@
|
|||
after some period of inactivity (the default threshold is 72h)."
|
||||
(:require
|
||||
[app.common.pages.migrations :as pmg]
|
||||
[app.common.spec :as us]
|
||||
[app.config :as cfg]
|
||||
[app.db :as db]
|
||||
[app.metrics :as mtx]
|
||||
[app.tasks :as tasks]
|
||||
[app.util.blob :as blob]
|
||||
[app.util.time :as dt]
|
||||
[integrant.core :as ig]
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.tools.logging :as log]))
|
||||
|
||||
(defn decode-row
|
||||
(declare handler)
|
||||
(declare retrieve-candidates)
|
||||
(declare process-file)
|
||||
|
||||
(defmethod ig/pre-init-spec ::handler [_]
|
||||
(s/keys :req-un [::db/pool]))
|
||||
|
||||
(defmethod ig/init-key ::handler
|
||||
[_ cfg]
|
||||
(partial handler cfg))
|
||||
|
||||
(defn- handler
|
||||
[{:keys [pool]} _]
|
||||
(db/with-atomic [conn pool]
|
||||
(loop []
|
||||
(let [files (retrieve-candidates conn)]
|
||||
(when (seq files)
|
||||
(run! (partial process-file conn) files)
|
||||
(recur))))))
|
||||
|
||||
;; (mtx/instrument-with-summary!
|
||||
;; {:var #'handler
|
||||
;; :id "tasks__file_media_gc"
|
||||
;; :help "Timing of task: file_media_gc"})
|
||||
|
||||
(defn- decode-row
|
||||
[{:keys [data] :as row}]
|
||||
(cond-> row
|
||||
(bytes? data) (assoc :data (blob/decode data))))
|
||||
|
||||
(def sql:retrieve-candidates-chunk
|
||||
(def ^:private
|
||||
sql:retrieve-candidates-chunk
|
||||
"select f.id,
|
||||
f.data,
|
||||
extract(epoch from (now() - f.modified_at))::bigint as age
|
||||
|
@ -37,9 +66,7 @@
|
|||
limit 10
|
||||
for update skip locked")
|
||||
|
||||
(defn retrieve-candidates
|
||||
"Retrieves a list of files that are candidates to be garbage
|
||||
collected."
|
||||
(defn- retrieve-candidates
|
||||
[conn]
|
||||
(let [threshold (:file-trimming-threshold cfg/config)
|
||||
interval (db/interval threshold)]
|
||||
|
@ -47,7 +74,8 @@
|
|||
(map (fn [{:keys [age] :as row}]
|
||||
(assoc row :age (dt/duration {:seconds age})))))))
|
||||
|
||||
(def collect-media-xf
|
||||
(def ^:private
|
||||
collect-media-xf
|
||||
(comp
|
||||
(map :objects)
|
||||
(mapcat vals)
|
||||
|
@ -92,19 +120,3 @@
|
|||
{:id id}))
|
||||
|
||||
nil))
|
||||
|
||||
(defn handler
|
||||
[_task]
|
||||
(db/with-atomic [conn db/pool]
|
||||
(loop []
|
||||
(let [files (retrieve-candidates conn)]
|
||||
(when (seq files)
|
||||
(run! (partial process-file conn) files)
|
||||
(recur))))))
|
||||
|
||||
|
||||
(mtx/instrument-with-summary!
|
||||
{:var #'handler
|
||||
:id "tasks__file_media_gc"
|
||||
:help "Timing of task: file_media_gc"})
|
||||
|
||||
|
|
|
@ -12,27 +12,38 @@
|
|||
change (transaction) log."
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[integrant.core :as ig]
|
||||
[app.db :as db]
|
||||
[app.metrics :as mtx]
|
||||
[app.util.time :as dt]
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.tools.logging :as log]))
|
||||
|
||||
(def max-age (dt/duration {:hours 12}))
|
||||
(declare handler)
|
||||
|
||||
(def sql:delete-files-xlog
|
||||
(s/def ::max-age ::dt/duration)
|
||||
(defmethod ig/pre-init-spec ::handler [_]
|
||||
(s/keys :req-un [::db/pool ::mtx/metrics ::max-age]))
|
||||
|
||||
(defmethod ig/init-key ::handler
|
||||
[_ {:keys [metrics] :as cfg}]
|
||||
(let [handler #(handler cfg %)]
|
||||
(->> {:registry (:registry metrics)
|
||||
:type :summary
|
||||
:name "task_file_xlog_gc_timing"
|
||||
:help "file changes garbage collection task timing"}
|
||||
(mtx/instrument handler))))
|
||||
|
||||
(def ^:private
|
||||
sql:delete-files-xlog
|
||||
"delete from task_completed
|
||||
where scheduled_at < now() - ?::interval")
|
||||
|
||||
(defn handler
|
||||
[{:keys [props] :as task}]
|
||||
(db/with-atomic [conn db/pool]
|
||||
(defn- handler
|
||||
[{:keys [pool max-age]} _]
|
||||
(db/with-atomic [conn pool]
|
||||
(let [interval (db/interval max-age)
|
||||
result (db/exec-one! conn [sql:delete-files-xlog interval])]
|
||||
(log/infof "removed %s rows from file_changes table." (:next.jdbc/update-count result))
|
||||
result (db/exec-one! conn [sql:delete-files-xlog interval])
|
||||
result (:next.jdbc/update-count result)]
|
||||
(log/infof "removed %s rows from file_changes table" result)
|
||||
nil)))
|
||||
|
||||
(mtx/instrument-with-summary!
|
||||
{:var #'handler
|
||||
:id "tasks__file_xlog_gc"
|
||||
:help "Timing of task: file_xlog_gc"})
|
||||
|
|
|
@ -8,13 +8,14 @@
|
|||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.tasks.remove-media
|
||||
"Demo accounts garbage collector."
|
||||
"TODO: pending to be refactored together with the storage
|
||||
subsystem."
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.db :as db]
|
||||
[app.media-storage :as mst]
|
||||
[app.metrics :as mtx]
|
||||
[app.util.storage :as ust]
|
||||
;; [app.media-storage :as mst]
|
||||
;; [app.metrics :as mtx]
|
||||
;; [app.util.storage :as ust]
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.tools.logging :as log]))
|
||||
|
||||
|
@ -26,21 +27,21 @@
|
|||
;; system. Mainly used for profile photo change; when we really know
|
||||
;; that the previous photo becomes unused.
|
||||
|
||||
(s/def ::path ::us/not-empty-string)
|
||||
(s/def ::props
|
||||
(s/keys :req-un [::path]))
|
||||
;; (s/def ::path ::us/not-empty-string)
|
||||
;; (s/def ::props
|
||||
;; (s/keys :req-un [::path]))
|
||||
|
||||
(defn handler
|
||||
[{:keys [props] :as task}]
|
||||
(us/verify ::props props)
|
||||
(when (ust/exists? mst/media-storage (:path props))
|
||||
(ust/delete! mst/media-storage (:path props))
|
||||
(log/debug "Media " (:path props) " removed.")))
|
||||
;; (defn handler
|
||||
;; [{:keys [props] :as task}]
|
||||
;; (us/verify ::props props)
|
||||
;; (when (ust/exists? mst/media-storage (:path props))
|
||||
;; (ust/delete! mst/media-storage (:path props))
|
||||
;; (log/debug "Media " (:path props) " removed.")))
|
||||
|
||||
(mtx/instrument-with-summary!
|
||||
{:var #'handler
|
||||
:id "tasks__remove_media"
|
||||
:help "Timing of remove-media task."})
|
||||
;; (mtx/instrument-with-summary!
|
||||
;; {:var #'handler
|
||||
;; :id "tasks__remove_media"
|
||||
;; :help "Timing of remove-media task."})
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Task: Trim Media Storage
|
||||
|
@ -59,37 +60,35 @@
|
|||
;; task (`remove-deleted-media`) permanently delete the file from the
|
||||
;; filesystem when is executed (by scheduler).
|
||||
|
||||
(def ^:private
|
||||
sql:retrieve-peding-to-delete
|
||||
"with items_part as (
|
||||
select i.id
|
||||
from pending_to_delete as i
|
||||
order by i.created_at
|
||||
limit ?
|
||||
for update skip locked
|
||||
)
|
||||
delete from pending_to_delete
|
||||
where id in (select id from items_part)
|
||||
returning *")
|
||||
|
||||
(defn trim-media-storage
|
||||
[_task]
|
||||
(letfn [(decode-row [{:keys [data] :as row}]
|
||||
(cond-> row
|
||||
(db/pgobject? data) (assoc :data (db/decode-json-pgobject data))))
|
||||
(retrieve-items [conn]
|
||||
(->> (db/exec! conn [sql:retrieve-peding-to-delete 10])
|
||||
(map decode-row)
|
||||
(map :data)))
|
||||
(remove-media [rows]
|
||||
(run! (fn [item]
|
||||
(let [path (get item "path")]
|
||||
(ust/delete! mst/media-storage path)))
|
||||
rows))]
|
||||
(loop []
|
||||
(let [rows (retrieve-items db/pool)]
|
||||
(when-not (empty? rows)
|
||||
(remove-media rows)
|
||||
(recur))))))
|
||||
|
||||
;; (def ^:private
|
||||
;; sql:retrieve-peding-to-delete
|
||||
;; "with items_part as (
|
||||
;; select i.id
|
||||
;; from pending_to_delete as i
|
||||
;; order by i.created_at
|
||||
;; limit ?
|
||||
;; for update skip locked
|
||||
;; )
|
||||
;; delete from pending_to_delete
|
||||
;; where id in (select id from items_part)
|
||||
;; returning *")
|
||||
|
||||
;; (defn trim-media-storage
|
||||
;; [_task]
|
||||
;; (letfn [(decode-row [{:keys [data] :as row}]
|
||||
;; (cond-> row
|
||||
;; (db/pgobject? data) (assoc :data (db/decode-json-pgobject data))))
|
||||
;; (retrieve-items [conn]
|
||||
;; (->> (db/exec! conn [sql:retrieve-peding-to-delete 10])
|
||||
;; (map decode-row)
|
||||
;; (map :data)))
|
||||
;; (remove-media [rows]
|
||||
;; (run! (fn [item]
|
||||
;; (let [path (get item "path")]
|
||||
;; (ust/delete! mst/media-storage path)))
|
||||
;; rows))]
|
||||
;; (loop []
|
||||
;; (let [rows (retrieve-items db/pool)]
|
||||
;; (when-not (empty? rows)
|
||||
;; (remove-media rows)
|
||||
;; (recur))))))
|
||||
|
|
|
@ -9,15 +9,50 @@
|
|||
|
||||
(ns app.tasks.sendmail
|
||||
(:require
|
||||
[app.common.spec :as us]
|
||||
[app.config :as cfg]
|
||||
[app.metrics :as mtx]
|
||||
[app.util.emails :as emails]
|
||||
[clojure.tools.logging :as log]))
|
||||
[clojure.tools.logging :as log]
|
||||
[clojure.spec.alpha :as s]
|
||||
[integrant.core :as ig]))
|
||||
|
||||
(declare handler)
|
||||
|
||||
(s/def ::username ::cfg/smtp-username)
|
||||
(s/def ::password ::cfg/smtp-password)
|
||||
(s/def ::tls ::cfg/smtp-tls)
|
||||
(s/def ::ssl ::cfg/smtp-ssl)
|
||||
(s/def ::host ::cfg/smtp-host)
|
||||
(s/def ::port ::cfg/smtp-port)
|
||||
(s/def ::default-reply-to ::cfg/smtp-default-reply-to)
|
||||
(s/def ::default-from ::cfg/smtp-default-from)
|
||||
(s/def ::enabled ::cfg/smtp-enabled)
|
||||
|
||||
(defmethod ig/pre-init-spec ::handler [_]
|
||||
(s/keys :req-un [::enabled ::mtx/metrics]
|
||||
:opt-un [::username
|
||||
::password
|
||||
::tls
|
||||
::ssl
|
||||
::host
|
||||
::port
|
||||
::default-from
|
||||
::default-reply-to]))
|
||||
|
||||
(defmethod ig/init-key ::handler
|
||||
[_ {:keys [metrics] :as cfg}]
|
||||
(let [handler #(handler cfg %)]
|
||||
(->> {:registry (:registry metrics)
|
||||
:type :summary
|
||||
:name "task_sendmail_timing"
|
||||
:help "sendmail task timing"}
|
||||
(mtx/instrument handler))))
|
||||
|
||||
(defn- send-console!
|
||||
[config email]
|
||||
[cfg email]
|
||||
(let [baos (java.io.ByteArrayOutputStream.)
|
||||
mesg (emails/smtp-message config email)]
|
||||
mesg (emails/smtp-message cfg email)]
|
||||
(.writeTo mesg baos)
|
||||
(let [out (with-out-str
|
||||
(println "email console dump:")
|
||||
|
@ -27,14 +62,7 @@
|
|||
(log/info out))))
|
||||
|
||||
(defn handler
|
||||
{:app.tasks/name "sendmail"}
|
||||
[{:keys [props] :as task}]
|
||||
(let [config (cfg/smtp cfg/config)]
|
||||
(if (:enabled config)
|
||||
(emails/send! config props)
|
||||
(send-console! config props))))
|
||||
|
||||
(mtx/instrument-with-summary!
|
||||
{:var #'handler
|
||||
:id "tasks__sendmail"
|
||||
:help "Timing of sendmail task."})
|
||||
[cfg {:keys [props] :as task}]
|
||||
(if (:enabled cfg)
|
||||
(emails/send! cfg props)
|
||||
(send-console! cfg props)))
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns app.tasks.clean-tasks-table
|
||||
(ns app.tasks.tasks-gc
|
||||
"A maintenance task that performs a cleanup of already executed tasks
|
||||
from the database table."
|
||||
(:require
|
||||
|
@ -16,25 +16,36 @@
|
|||
[app.metrics :as mtx]
|
||||
[app.util.time :as dt]
|
||||
[clojure.spec.alpha :as s]
|
||||
[clojure.tools.logging :as log]))
|
||||
[clojure.tools.logging :as log]
|
||||
[integrant.core :as ig]))
|
||||
|
||||
(def max-age (dt/duration {:hours 24}))
|
||||
(declare handler)
|
||||
|
||||
(def sql:delete-completed-tasks
|
||||
(s/def ::max-age ::dt/duration)
|
||||
|
||||
(defmethod ig/pre-init-spec ::handler [_]
|
||||
(s/keys :req-un [::db/pool ::mtx/metrics ::max-age]))
|
||||
|
||||
(defmethod ig/init-key ::handler
|
||||
[_ {:keys [metrics] :as cfg}]
|
||||
(let [handler #(handler cfg %)]
|
||||
(->> {:registry (:registry metrics)
|
||||
:type :summary
|
||||
:name "task_tasks_gc_timing"
|
||||
:help "tasks garbage collection task timing"}
|
||||
(mtx/instrument handler))))
|
||||
|
||||
(def ^:private
|
||||
sql:delete-completed-tasks
|
||||
"delete from task_completed
|
||||
where scheduled_at < now() - ?::interval")
|
||||
|
||||
(defn handler
|
||||
[task]
|
||||
(db/with-atomic [conn db/pool]
|
||||
(defn- handler
|
||||
[{:keys [pool max-age]} _]
|
||||
(db/with-atomic [conn pool]
|
||||
(let [interval (db/interval max-age)
|
||||
result (db/exec-one! conn [sql:delete-completed-tasks interval])]
|
||||
(log/infof "removed %s rows from tasks_completed table." (:next.jdbc/update-count result))
|
||||
result (db/exec-one! conn [sql:delete-completed-tasks interval])
|
||||
result (:next.jdbc/update-count result)]
|
||||
(log/infof "removed %s rows from tasks_completed table" result)
|
||||
nil)))
|
||||
|
||||
(mtx/instrument-with-summary!
|
||||
{:var #'handler
|
||||
:id "tasks__clean_tasks_table"
|
||||
:help "Timing of task: clean_task_table"})
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue