[tor-commits] [atlas/master] Fixes long-lived performance bug; max result set size to 2000

irl at torproject.org irl at torproject.org
Sun Nov 26 14:37:32 UTC 2017


commit b02efd6b0cb5263c37bd81f6f16b4cdeba5b11b7
Author: Iain R. Learmonth <irl at fsfe.org>
Date:   Sun Nov 26 02:21:40 2017 +0000

    Fixes long-lived performance bug; max result set size to 2000
    
     * The Backbone.js collection for the search results was being updated
       for every relay "looked up", when really this should only have
       happened when all relays had been processed.
     * Relays are now loaded in chunks, with a progress bar updating
       to show how many have been loaded.
     * When loading the secondary search box is removed from view as the
       updates are happening asynchronously and bad things would happen if
       the load was interrupted by a second search.
---
 css/atlas.css             |  4 +--
 index.html                |  2 +-
 js/collections/results.js | 49 +++++++++++++++++++++---------------
 js/helpers.js             |  9 +++++++
 js/router.js              | 64 ++++++++++++++++++++++++++---------------------
 templates/search/do.html  |  4 +--
 6 files changed, 78 insertions(+), 54 deletions(-)

diff --git a/css/atlas.css b/css/atlas.css
index cdbec5e..41f799f 100644
--- a/css/atlas.css
+++ b/css/atlas.css
@@ -4,8 +4,8 @@
     display: none;
 }
 
-.progress .bar {
-    width: 50%;
+.progress-bar {
+    width: 100%;
 }
 
 a.alleged {
diff --git a/index.html b/index.html
index 9ab3516..10aa909 100644
--- a/index.html
+++ b/index.html
@@ -151,7 +151,7 @@
   </form>
   <h1>Relay Search</h1>
   <div class="progress progress-info progress-striped active">
-    <div class="progress-bar"></div>
+    <div class="progress-bar">Rendering results...</div>
   </div>
   <div id="content">
     <noscript>
diff --git a/js/collections/results.js b/js/collections/results.js
index da8a6a4..73ef819 100644
--- a/js/collections/results.js
+++ b/js/collections/results.js
@@ -41,29 +41,38 @@ define([
                 if (relays.length == 0) {
                     error(0);
                     return false;
-                } else if (relays.length > 500) {
-                   relays = relays.slice(0, 500);
+                } else if (relays.length > 2000) {
+                   relays = relays.slice(0, 2000);
                    err = 4;
                 }
                 var lookedUpRelays = 0;
-                _.each(relays, function(relay) {
-                    var lookedUp = function() {
-                      lookedUpRelays++;
-                      if (lookedUpRelays == relays.length) {
-                        success(err, relaysPublished, bridgesPublished);
-                      }
-                    }
-                    relay.lookup({
-                        success: function(){
-                            collection[options.add ? 'add' : 'reset'](relays, options);
-                            lookedUp();
-                        },
-                        error: function() {
-                            lookedUp();
-                            error(0);
-                        }
-                    });
-                });
+                var relayChunks = relays.chunk(600);
+                var chunkedLookup = function() {
+                  _.each(relayChunks.pop(), function(relay) {
+                      relay.lookup({
+                          success: function(){
+                              lookedUpRelays++;
+                          },
+                          error: function() {
+                              lookedUpRelays++;
+                              error(0);
+                          }
+                      });
+                  });
+                  if (lookedUpRelays == relays.length) {
+                    $('.progress-bar').width("100%");
+                    $('.progress-bar').html("Rendering results...");
+                    setTimeout(function() {
+                      collection[options.add ? 'add' : 'reset'](relays, options);
+                      success(err, relaysPublished, bridgesPublished);
+                    }, 500);
+                  } else {
+                    $('.progress-bar').width((lookedUpRelays / relays.length * 100) + "%");
+                    $('.progress-bar').html(lookedUpRelays + " of " + relays.length + " loaded");
+                    setTimeout(chunkedLookup, 50);
+                  }
+                }
+                chunkedLookup();
             }).fail(
                 function(jqXHR, textStatus, errorThrown) {
                 if(jqXHR.statusText == "error") {
diff --git a/js/helpers.js b/js/helpers.js
index 214db67..457702b 100644
--- a/js/helpers.js
+++ b/js/helpers.js
@@ -278,3 +278,12 @@ window.onhashchange = function(){
         $('.btn-navbar').click();
     }
 }
+
+Object.defineProperty(Array.prototype, 'chunk', {
+    value: function(chunkSize) {
+        var R = [];
+        for (var i=0; i<this.length; i+=chunkSize)
+            R.push(this.slice(i,i+chunkSize));
+        return R;
+    }
+});
diff --git a/js/router.js b/js/router.js
index 118c094..fed87ba 100644
--- a/js/router.js
+++ b/js/router.js
@@ -61,23 +61,24 @@ define([
     // Empty aggregation query
     emptyAggregateSearch: function() {
         $(".breadcrumb").html("<li><a href=\"https://metrics.torproject.org/\">Home</a></li><li><a href=\"https://metrics.torproject.org/services.html\">Services</a></li><li><a href=\"#\">Relay Search</a></li><li class=\"active\">Error</li>");
-        $("#secondary-search").show();
         $("#secondary-search-query").val("");
 
+        $("#secondary-search").hide();
         $("#content").hide();
         $(".progress").show();
-          doSearchView.error = 5;
-          doSearchView.renderError();
-            $(".progress").hide();
-            $("#content").show();
+        aggregateSearchView.error = 5;
+        aggregateSearchView.renderError();
+        $(".progress").hide();
+        $("#secondary-search").show();
+        $("#content").show();
 
     },
     // Perform a countries aggregation
     aggregateSearch: function(aType, query){
         $(".breadcrumb").html("<li><a href=\"https://metrics.torproject.org/\">Home</a></li><li><a href=\"https://metrics.torproject.org/services.html\">Services</a></li><li><a href=\"#\">Relay Search</a></li><li class=\"active\">Aggregated search" + ((query) ? " for " + query : "") + "</li>");
-        $("#secondary-search").show();
 
         $("#content").hide();
+        $("#secondary-search").hide();
         $(".progress").show();
 
         aggregateSearchView.collection.aType = (aType) ? aType : "all";
@@ -100,12 +101,14 @@ define([
           aggregateSearchView.render(query);
           $("#search-title").text("Aggregated results" + ((query) ? " for " + query : ""));
           $(".progress").hide();
+          $("#secondary-search").show();
           $("#content").show();
         },
         error: function(err){
           aggregateSearchView.error = err;
           aggregateSearchView.renderError();
           $(".progress").hide();
+          $("#secondary-search").show();
           $("#content").show();
         }
       });
@@ -114,8 +117,8 @@ define([
     // Perform a search on Atlas
     doSearch: function(query){
         $(".breadcrumb").html("<li><a href=\"https://metrics.torproject.org/\">Home</a></li><li><a href=\"https://metrics.torproject.org/services.html\">Services</a></li><li><a href=\"#\">Relay Search</a></li><li class=\"active\">Search for " + query + "</li>");
-        $("#secondary-search").show();
 
+        $("#secondary-search").hide();
         $("#content").hide();
         $(".progress").show();
 
@@ -124,37 +127,40 @@ define([
             doSearchView.renderError();
             $(".progress").hide();
             $("#content").show();
+            $("#secondary-search").show();
         } else {
           query = query.trim();
           $("#secondary-search-query").val(query);
           doSearchView.collection.url =
               doSearchView.collection.baseurl + this.hashFingerprint(query);
           doSearchView.collection.lookup({
-                success: function(err, relaysPublished, bridgesPublished){
-                    doSearchView.relays = doSearchView.collection.models;
-                    // Redirect to the details page when there is exactly one
-                    // search result.
-                    if (doSearchView.relays.length == 1) {
-                        document.location.replace("#details/" +
-                            doSearchView.relays[0].fingerprint);
-                        return;
-                    }
+              success: function(err, relaysPublished, bridgesPublished){
+                  doSearchView.relays = doSearchView.collection.models;
+                  // Redirect to the details page when there is exactly one
+                  // search result.
+                  if (doSearchView.relays.length == 1) {
+                      document.location.replace("#details/" +
+                          doSearchView.relays[0].fingerprint);
+                      return;
+                  }
 		    doSearchView.error = err;
-                    doSearchView.relaysPublished = relaysPublished;
-                    doSearchView.bridgesPublished = bridgesPublished;
-                    doSearchView.render(query);
-		    $("#search-title").text(query);
-                    $(".progress").hide();
-                    $("#content").show();
-                },
-
-                error: function(err){
+                  doSearchView.relaysPublished = relaysPublished;
+                  doSearchView.bridgesPublished = bridgesPublished;
+                  doSearchView.render(query);
+		  $("#search-title").text(query);
+                  $("#secondary-search").show();
+                  $(".progress").hide();
+                  $("#content").show();
+              },
+
+              error: function(err){
 		    doSearchView.error = err;
 		    doSearchView.renderError();
-                    $(".progress").hide();
-                    $("#content").show();
-                }
-            });
+                  $(".progress").hide();
+                  $("#content").show();
+                  $("#secondary-search").show();
+              }
+          });
         }
     },
     showTopRelays: function(){
diff --git a/templates/search/do.html b/templates/search/do.html
index fb32fdb..3935182 100644
--- a/templates/search/do.html
+++ b/templates/search/do.html
@@ -39,8 +39,8 @@
     <% if (error == 4) { %>
     <div class="alert alert-warning">
         <strong>Too many matches!</strong><p>The current version of
-        Relay Search does not support a result set greater than 500 and only displays
-        the first 500 hits. This is due to some performance issues in rendering
+        Relay Search does not support a result set greater than 2000 and only displays
+        the first 2000 hits. This is due to some performance issues in rendering
         large results sets in JavaScript. Future versions will
         hopefully manage to overcome this issue.</p>
 	<% if ( ! query.includes("running:true") ) { %><p>You may find it





More information about the tor-commits mailing list