♻️ Replace mount with integrant.

This commit is contained in:
Andrey Antukh 2020-12-24 14:32:19 +01:00 committed by Alonso Torres
parent 31d7aacec1
commit 9f12456456
76 changed files with 2403 additions and 2215 deletions

View file

@ -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"]

View file

@ -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)

View file

@ -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"})

View file

@ -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"})

View file

@ -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))))))

View file

@ -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)))

View file

@ -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"})