rebaseline_server: return rebaseline results faster, and reload UI page automatically after

Old way:
Wait until server has loaded the updated results before telling the user the rebaseline
was successful, and trust the user to reload the page before submitting more baselines.

New way:
Make server load the updated results in a separate thread, and automatically reload the page
so that the user can submit more baselines if she wants to.

(SkipBuildbotRuns)
NOTRY=True
NOTREECHECKS=True
R=bsalomon@google.com

Author: epoger@google.com

Review URL: https://codereview.chromium.org/117453002

git-svn-id: http://skia.googlecode.com/svn/trunk@12717 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/rebaseline_server/server.py b/gm/rebaseline_server/server.py
index e8dbb6b..d1d9c85 100755
--- a/gm/rebaseline_server/server.py
+++ b/gm/rebaseline_server/server.py
@@ -157,8 +157,8 @@
 
   @property
   def results(self):
-    """ Returns the most recently generated results, or None if update_results()
-    has not been called yet. """
+    """ Returns the most recently generated results, or None if we don't have
+    any valid results (update_results() has not completed yet). """
     return self._results
 
   @property
@@ -178,15 +178,22 @@
     results. """
     return self._reload_seconds
 
-  def update_results(self):
+  def update_results(self, invalidate=False):
     """ Create or update self._results, based on the expectations in
     EXPECTATIONS_DIR and the latest actuals from skia-autogen.
 
     We hold self.results_rlock while we do this, to guarantee that no other
     thread attempts to update either self._results or the underlying files at
     the same time.
+
+    Args:
+      invalidate: if True, invalidate self._results immediately upon entry;
+                  otherwise, we will let readers see those results until we
+                  replace them
     """
     with self.results_rlock:
+      if invalidate:
+        self._results = None
       logging.info('Updating actual GM results in %s from SVN repo %s ...' % (
           self._actuals_dir, ACTUALS_SVN_REPO))
       self._actuals_repo.Update('.')
@@ -445,8 +452,11 @@
                         'results and submit the modifications again.' %
                         oldResultsType)
       _SERVER.results.edit_expectations(data['modifications'])
-      # Read the updated results back from disk.
-      _SERVER.update_results()
+
+    # Read the updated results back from disk.
+    # We can do this in a separate thread; we should return our success message
+    # to the UI as soon as possible.
+    thread.start_new_thread(_SERVER.update_results, (True,))
 
   def redirect_to(self, url):
     """ Redirect the HTTP client to a different url.
diff --git a/gm/rebaseline_server/static/loader.js b/gm/rebaseline_server/static/loader.js
index fa74ed8..3339cad 100644
--- a/gm/rebaseline_server/static/loader.js
+++ b/gm/rebaseline_server/static/loader.js
@@ -55,7 +55,7 @@
       function(data, status, header, config) {
         if (data.header.resultsStillLoading) {
           $scope.loadingMessage =
-              "Server is still loading initial results; will retry at " +
+              "Server is still loading results; will retry at " +
               $scope.localTimeString(data.header.timeNextUpdateAvailable);
           $timeout(
               function(){location.reload();},
@@ -508,9 +508,13 @@
         alert("New baselines submitted successfully!\n\n" +
             "You still need to commit the updated expectations files on " +
             "the server side to the Skia repo.\n\n" +
-            "Also: in order to see the complete updated data, or to submit " +
-            "more baselines, you will need to reload your client.");
-        $scope.submitPending = false;
+            "When you click OK, your web UI will reload; after that " +
+            "completes, you will see the updated data (once the server has " +
+            "finished loading the update results into memory!) and you can " +
+            "submit more baselines if you want.");
+        // I don't know why, but if I just call reload() here it doesn't work.
+        // Making a timer call it fixes the problem.
+        $timeout(function(){location.reload();}, 1);
       }).error(function(data, status, headers, config) {
         alert("There was an error submitting your baselines.\n\n" +
             "Please see server-side log for details.");