From 44e9db1726fe978321dc9e098cf574fc7f52bcea Mon Sep 17 00:00:00 2001
From: dpsutton <dan@dpsutton.com>
Date: Thu, 12 May 2022 09:16:53 -0500
Subject: [PATCH] Start task scheduler at end of startup. (#22649)

* Start task scheduler at end of startup.

The sync db task does a lot of db work to be addressed in a later
commit. But it also begins firing tasks _during startup_. Lets prevent
syncs and other tasks while we are starting up until we have finished.

Scheduler can be set to standby mode while we wait on finishing up
initializing and then start after.

* docstring cleanup and comments
---
 src/metabase/core.clj |  6 ++++--
 src/metabase/task.clj | 17 ++++++++++++++---
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/src/metabase/core.clj b/src/metabase/core.clj
index 089a549f8f6..d3cc2c1262a 100644
--- a/src/metabase/core.clj
+++ b/src/metabase/core.clj
@@ -104,8 +104,8 @@
     (events/initialize-events!)
     (init-status/set-progress! 0.7)
 
-    ;; Now start the task runner
-    (task/start-scheduler!)
+    ;; Now initialize the task runner
+    (task/init-scheduler!)
     (init-status/set-progress! 0.8)
 
     (when new-install?
@@ -123,6 +123,8 @@
       ;; otherwise update if appropriate
       (sample-data/update-sample-database-if-needed!)))
 
+  ;; start scheduler at end of init!
+  (task/start-scheduler!)
   (init-status/set-complete!)
   (log/info (trs "Metabase Initialization COMPLETE")))
 
diff --git a/src/metabase/task.clj b/src/metabase/task.clj
index 625091faa89..f8af6d20837 100644
--- a/src/metabase/task.clj
+++ b/src/metabase/task.clj
@@ -146,8 +146,9 @@
   (when (= (mdb/db-type) :postgres)
     (System/setProperty "org.quartz.jobStore.driverDelegateClass" "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate")))
 
-(defn start-scheduler!
-  "Start our Quartzite scheduler which allows jobs to be submitted and triggers to begin executing."
+(defn init-scheduler!
+  "Initialize our Quartzite scheduler which allows jobs to be submitted and triggers to scheduled. Puts scheduler in
+  standby mode. Call [[start-scheduler!]] to begin running scheduled tasks."
   []
   (classloader/the-classloader)
   (when-not @quartz-scheduler
@@ -155,9 +156,19 @@
     (let [new-scheduler (qs/initialize)]
       (when (compare-and-set! quartz-scheduler nil new-scheduler)
         (find-and-load-task-namespaces!)
-        (qs/start new-scheduler)
+        (qs/standby new-scheduler)
+        (log/info (trs "Task scheduler initialized into standby mode."))
         (init-tasks!)))))
 
+(defn start-scheduler!
+  "Start an initialized scheduler. Tasks do not run before calling this function. It is an error to call this function
+  when [[quartz-scheduler]] has not been set. The function [[init-scheduler!]] will initialize this correctly."
+  []
+  (if-let [scheduler @quartz-scheduler]
+    (do (qs/start scheduler)
+        (log/info (trs "Task scheduler started")))
+    (throw (trs "Scheduler not initialized but `start-scheduler!` called. Please call `init-scheduler!` before attempting to start."))))
+
 (defn stop-scheduler!
   "Stop our Quartzite scheduler and shutdown any running executions."
   []
-- 
GitLab