0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-02 20:39:09 -05:00

Merge pull request #4450 from penpot/niwinz-staging-bugfix-1

 Make cron task schedule sync more lock resilent
This commit is contained in:
Alejandro 2024-04-16 09:28:03 +02:00 committed by GitHub
commit 4dacba6836
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -27,14 +27,15 @@
"insert into scheduled_task (id, cron_expr) "insert into scheduled_task (id, cron_expr)
values (?, ?) values (?, ?)
on conflict (id) on conflict (id)
do update set cron_expr=?") do nothing")
(defn- synchronize-cron-entries! (defn- synchronize-cron-entries!
[{:keys [::db/pool ::entries]}] [{:keys [::db/conn ::entries]}]
(db/with-atomic [conn pool] (doseq [{:keys [id cron]} entries]
(doseq [{:keys [id cron]} entries] (let [result (db/exec-one! conn [sql:upsert-cron-task id (str cron)])
(l/trc :hint "register cron task" :id id :cron (str cron)) updated? (pos? (db/get-update-count result))]
(db/exec-one! conn [sql:upsert-cron-task id (str cron) (str cron)])))) (l/dbg :hint "register task" :id id :cron (str cron)
:status (if updated? "created" "exists")))))
(defn- lock-scheduled-task! (defn- lock-scheduled-task!
[conn id] [conn id]
@ -45,7 +46,7 @@
(declare ^:private schedule-cron-task) (declare ^:private schedule-cron-task)
(defn- execute-cron-task (defn- execute-cron-task
[cfg {:keys [id] :as task}] [cfg {:keys [id cron] :as task}]
(px/thread (px/thread
{:name (str "penpot/cron-task/" id)} {:name (str "penpot/cron-task/" id)}
(let [tpoint (dt/tpoint)] (let [tpoint (dt/tpoint)]
@ -54,20 +55,25 @@
(db/exec-one! conn ["SET LOCAL statement_timeout=0;"]) (db/exec-one! conn ["SET LOCAL statement_timeout=0;"])
(db/exec-one! conn ["SET LOCAL idle_in_transaction_session_timeout=0;"]) (db/exec-one! conn ["SET LOCAL idle_in_transaction_session_timeout=0;"])
(when (lock-scheduled-task! conn id) (when (lock-scheduled-task! conn id)
(l/dbg :hint "start task" :task-id id) (db/update! conn :scheduled-task
{:cron-expr (str cron)
:modified-at (dt/now)}
{:id id}
{::db/return-keys false})
(l/dbg :hint "start" :id id)
((:fn task) task) ((:fn task) task)
(let [elapsed (dt/format-duration (tpoint))] (let [elapsed (dt/format-duration (tpoint))]
(l/dbg :hint "end task" :task-id id :elapsed elapsed))))) (l/dbg :hint "end" :id id :elapsed elapsed)))))
(catch InterruptedException _ (catch InterruptedException _
(let [elapsed (dt/format-duration (tpoint))] (let [elapsed (dt/format-duration (tpoint))]
(l/debug :hint "task interrupted" :task-id id :elapsed elapsed))) (l/debug :hint "task interrupted" :id id :elapsed elapsed)))
(catch Throwable cause (catch Throwable cause
(let [elapsed (dt/format-duration (tpoint))] (let [elapsed (dt/format-duration (tpoint))]
(binding [l/*context* (get-error-context cause task)] (binding [l/*context* (get-error-context cause task)]
(l/err :hint "unhandled exception on running task" (l/err :hint "unhandled exception on running task"
:task-id id :id id
:elapsed elapsed :elapsed elapsed
:cause cause)))) :cause cause))))
(finally (finally
@ -86,7 +92,7 @@
(let [ts (ms-until-valid cron) (let [ts (ms-until-valid cron)
ft (px/schedule! ts (partial execute-cron-task cfg task))] ft (px/schedule! ts (partial execute-cron-task cfg task))]
(l/dbg :hint "schedule task" :task-id id (l/dbg :hint "schedule task" :id id
:ts (dt/format-duration ts) :ts (dt/format-duration ts)
:at (dt/format-instant (dt/in-future ts))) :at (dt/format-instant (dt/in-future ts)))
@ -135,7 +141,8 @@
cfg (assoc cfg ::entries entries ::running running)] cfg (assoc cfg ::entries entries ::running running)]
(l/inf :hint "started" :tasks (count entries)) (l/inf :hint "started" :tasks (count entries))
(synchronize-cron-entries! cfg)
(db/tx-run! cfg synchronize-cron-entries!)
(->> (filter some? entries) (->> (filter some? entries)
(run! (partial schedule-cron-task cfg))) (run! (partial schedule-cron-task cfg)))