From ab604f2972f88aa46003e3ca10c0aaea331b2964 Mon Sep 17 00:00:00 2001
From: Dennis Schridde <63082+devurandom@users.noreply.github.com>
Date: Fri, 18 Oct 2024 17:43:11 +0200
Subject: [PATCH] Self-heal database sync triggers (#48882)

== Behaviour without this fix ==

See #48881

== Behaviour with this fix ==

1. Metabase starts with an empty application database, and a config file
   containing configuration for a connected database
3. By the time it reaches "INFO metabase.task :: Task scheduler started",
   `qrtz_triggers` contains `metabase.task.sync-and-analyze.trigger.1`
   (sample DB) and `metabase.task.sync-and-analyze.trigger.2` (DB from
   config file)

Closes: https://github.com/metabase/metabase/issues/48881
Co-authored-by: Noah Moss <noah@metabase.com>
---
 src/metabase/core.clj            |  3 +++
 src/metabase/models/database.clj | 12 ++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/src/metabase/core.clj b/src/metabase/core.clj
index 3eb2f117d38..a8cfd16f754 100644
--- a/src/metabase/core.clj
+++ b/src/metabase/core.clj
@@ -17,6 +17,7 @@
    [metabase.events :as events]
    [metabase.logger :as logger]
    [metabase.models.cloud-migration :as cloud-migration]
+   [metabase.models.database :as database]
    [metabase.models.setting :as settings]
    [metabase.plugins :as plugins]
    [metabase.plugins.classloader :as classloader]
@@ -163,6 +164,8 @@
   (settings/migrate-encrypted-settings!)
   ;; start scheduler at end of init!
   (task/start-scheduler!)
+  ;; In case we could not do this earlier (e.g. for DBs added via config file), because the scheduler was not up yet:
+  (database/check-and-schedule-tasks!)
   ;; load the channels
   (channel/find-and-load-metabase-channels!)
   (init-status/set-complete!)
diff --git a/src/metabase/models/database.clj b/src/metabase/models/database.clj
index ac5e117d430..4977da64aae 100644
--- a/src/metabase/models/database.clj
+++ b/src/metabase/models/database.clj
@@ -136,6 +136,12 @@
     (catch Throwable e
       (log/error e "Error scheduling tasks for DB"))))
 
+(defn check-and-schedule-tasks!
+  "(Re)schedule sync operation tasks for any database which is not yet being synced regularly."
+  []
+  (doseq [database (t2/select :model/Database)]
+    (check-and-schedule-tasks-for-db! database)))
+
 ;; TODO - something like NSNotificationCenter in Objective-C would be really really useful here so things that want to
 ;; implement behavior when an object is deleted can do it without having to put code here
 
@@ -169,6 +175,9 @@
   (u/prog1 database
     (set-new-database-permissions! database)
     ;; schedule the Database sync & analyze tasks
+    ;; This will not do anything when coming from [[metabase-enterprise.advanced-config.file/initialize!]],
+    ;; since the scheduler will not be up yet.
+    ;; Thus, we call [[metabase.task.sync-databases/check-and-schedule-tasks!]] from [[metabase.core/init!]] to self-heal.
     (check-and-schedule-tasks-for-db! (t2.realize/realize database))))
 
 (def ^:private ^:dynamic *normalizing-details*
@@ -319,6 +328,9 @@
 
 (t2/define-after-update :model/Database
   [database]
+  ;; This will not do anything when coming from [[metabase-enterprise.advanced-config.file/initialize!]],
+  ;; since the scheduler will not be up yet.
+  ;; Thus, we call [[metabase.task.sync-databases/check-and-schedule-tasks!]] from [[metabase.core/init!]] to self-heal.
   (check-and-schedule-tasks-for-db! (t2.realize/realize database)))
 
 (t2/define-before-insert :model/Database
-- 
GitLab