From a6b307c1e24adc57b70b95a893c661d1aee81a64 Mon Sep 17 00:00:00 2001
From: Tom Robinson <tlrobinson@gmail.com>
Date: Wed, 21 Oct 2015 16:27:00 -0700
Subject: [PATCH] Initialization progress bar

---
 resources/frontend_client/init.html | 31 +++++++++++++++++++++++++----
 src/metabase/api/routes.clj         |  2 +-
 src/metabase/core.clj               | 20 +++++++++++++++----
 3 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/resources/frontend_client/init.html b/resources/frontend_client/init.html
index 69890ac4581..20bd5238b7c 100644
--- a/resources/frontend_client/init.html
+++ b/resources/frontend_client/init.html
@@ -5,11 +5,34 @@
     <title>Metabase</title>
   </head>
   <body>
-    Initializing Metabase, please wait...
+
+    <h3>Initializing Metabase, please wait...</h3>
+    <div>
+      <progress id="progress" max="100" value="0"></progress>
+    </div>
+
     <script type="text/javascript">
-      setTimeout(function() {
-        window.location.reload();
-      }, 2500);
+      function poll() {
+        var req = new XMLHttpRequest();
+        req.open("GET", "/api/health", true);
+        req.onreadystatechange = function() {
+          if (req.readyState === 4) {
+            if (req.status === 200) {
+              window.location.reload();
+            } else {
+              try {
+                var health = JSON.parse(req.responseText);
+                if (typeof health.progress === "number") {
+                  document.getElementById("progress").value = health.progress * 100;
+                }
+              } catch (e) {}
+              setTimeout(poll, 500);
+            }
+          }
+        }
+        req.send();
+      }
+      poll();
     </script>
   </body>
 </html>
diff --git a/src/metabase/api/routes.clj b/src/metabase/api/routes.clj
index 49c8736e58e..e13507ad311 100644
--- a/src/metabase/api/routes.clj
+++ b/src/metabase/api/routes.clj
@@ -37,7 +37,7 @@
   (context "/foreignkey"   [] (+auth fk/routes))
   (GET     "/health"       [] (if ((resolve 'metabase.core/initialized?))
                                   {:status 200 :body {:status "ok"}}
-                                  {:status 503 :body {:status "initializing"}}))
+                                  {:status 503 :body {:status "initializing" :progress ((resolve 'metabase.core/initialization-progress))}}))
   (context "/notify"       [] (+apikey notify/routes))
   (context "/revision"     [] (+auth revision/routes))
   (context "/session"      [] session/routes)
diff --git a/src/metabase/core.clj b/src/metabase/core.clj
index a03e4d4414d..a34d968b06a 100644
--- a/src/metabase/core.clj
+++ b/src/metabase/core.clj
@@ -71,13 +71,18 @@
 
 ;;; ## ---------------------------------------- LIFECYCLE ----------------------------------------
 
-(def ^:private metabase-initialized
-  (atom false))
+(def ^:private metabase-initialization-progress
+  (atom 0))
 
 (defn initialized?
   "Metabase is initialized and ready to be served"
   []
-  @metabase-initialized)
+  (= @metabase-initialization-progress 1.0))
+
+(defn initialization-progress
+  "Metabase is initialized and ready to be served"
+  []
+  @metabase-initialization-progress)
 
 (defn- -init-create-setup-token
   "Create and set a new setup token, and open the setup URL on the user's system."
@@ -104,11 +109,15 @@
   "General application initialization function which should be run once at application startup."
   []
   (log/info (format "Starting Metabase version %s..." (config/mb-version-string)))
+  (reset! metabase-initialization-progress 0.1)
+
   ;; First of all, lets register a shutdown hook that will tidy things up for us on app exit
   (.addShutdownHook (Runtime/getRuntime) (Thread. ^Runnable destroy))
+  (reset! metabase-initialization-progress 0.3)
 
   ;; startup database.  validates connection & runs any necessary migrations
   (db/setup-db :auto-migrate (config/config-bool :mb-db-automigrate))
+  (reset! metabase-initialization-progress 0.5)
 
   ;; run a very quick check to see if we are doing a first time installation
   ;; the test we are using is if there is at least 1 User in the database
@@ -116,9 +125,11 @@
 
     ;; Bootstrap the event system
     (events/initialize-events!)
+    (reset! metabase-initialization-progress 0.7)
 
     ;; Now start the task runner
     (task/start-scheduler!)
+    (reset! metabase-initialization-progress 0.8)
 
     (when new-install
       (log/info "Looks like this is a new installation ... preparing setup wizard")
@@ -126,6 +137,7 @@
       (-init-create-setup-token)
       ;; publish install event
       (events/publish-event :install {}))
+    (reset! metabase-initialization-progress 0.9)
 
     ;; deal with our sample dataset as needed
     (if new-install
@@ -135,7 +147,7 @@
       (sample-data/update-sample-dataset-if-needed!)))
 
   (log/info "Metabase Initialization COMPLETE")
-  (reset! metabase-initialized true)
+  (reset! metabase-initialization-progress 1.0)
   true)
 
 
-- 
GitLab