HTRACE-334. htrace-web: Make limit of search and children API configurable (iwasakims via cmccabe)
diff --git a/htrace-webapp/src/main/webapp/app/search_view.js b/htrace-webapp/src/main/webapp/app/search_view.js
index 5936410..b5abd1f 100644
--- a/htrace-webapp/src/main/webapp/app/search_view.js
+++ b/htrace-webapp/src/main/webapp/app/search_view.js
@@ -80,9 +80,11 @@
         return false;
       }
     }
+    var lim = Math.min(parseInt($("#search-lim").val()) || 20, 200);
+    $("#search-lim").val(lim.toString());
     var queryJson = {
       pred: predicates,
-      lim: 20
+      lim: lim
     };
     // If there are existing search results, we want results which "come after"
     // those.  So pass the last span we saw as a continuation token.
diff --git a/htrace-webapp/src/main/webapp/app/span.js b/htrace-webapp/src/main/webapp/app/span.js
index ca867ec..20944b9 100644
--- a/htrace-webapp/src/main/webapp/app/span.js
+++ b/htrace-webapp/src/main/webapp/app/span.js
@@ -219,18 +219,19 @@
     return rootDeferred.promise();
   },
 
-  reifyChildrenRecursive: function(depth) {
+  reifyChildrenRecursive: function(depth, lim) {
     var rootDeferred = jQuery.Deferred();
     var span = this;
-    span.reifyChildren().done(function(err) {
-      if ((err != "") || (depth <= 0)) {
+    span.reifyChildren(lim).done(function(err) {
+      var reifiedChildren = span.get("reifiedChildren");
+      lim = lim - reifiedChildren.length;
+      if ((err != "") || (depth <= 0) || (lim <= 0)) {
         rootDeferred.resolve(err);
         return;
       }
       var recursivePromises = [];
-      var reifiedChildren = span.get("reifiedChildren");
       for (var j = 0; j < reifiedChildren.length; j++) {
-        recursivePromises.push(reifiedChildren[j].reifyChildrenRecursive(depth - 1));
+        recursivePromises.push(reifiedChildren[j].reifyChildrenRecursive(depth - 1, lim));
       }
       $.when.apply($, recursivePromises).then(function() {
         for (var i = 0; i < arguments.length; i++) {
@@ -253,11 +254,11 @@
   // this span and stores them into reifiedChildren.  The promise returns the
   // empty string on success, or an error string on failure.
   //
-  reifyChildren: function() {
+  reifyChildren: function(lim) {
     var rootDeferred = jQuery.Deferred();
     var span = this;
     $.ajax({
-        url: "span/" + span.get("spanId") + "/children?lim=50",
+        url: "span/" + span.get("spanId") + "/children?lim=" + lim.toString(),
         data: {},
         contentType: "application/json; charset=utf-8",
         dataType: "json"
@@ -288,8 +289,8 @@
           for (var j = 0; j < reifiedChildren.length; j++) {
             reifiedChildren[j].set("reifiedParents", [span]);
           }
-          console.log("Setting reified children for " + span.get("spanId") +
-              " to " + htrace.spanModelsToString (reifiedChildren));
+          //console.log("Setting reified children for " + span.get("spanId") +
+          //    " to " + htrace.spanModelsToString (reifiedChildren));
           span.set("reifiedChildren", reifiedChildren);
           rootDeferred.resolve("");
         });
diff --git a/htrace-webapp/src/main/webapp/app/span_widget.js b/htrace-webapp/src/main/webapp/app/span_widget.js
index ba70577..8ebe4a7 100644
--- a/htrace-webapp/src/main/webapp/app/span_widget.js
+++ b/htrace-webapp/src/main/webapp/app/span_widget.js
@@ -246,7 +246,9 @@
       case "dblclick":
         if (htrace.inBoundingBox(e.x, e.y,
             this.x0, this.xF, this.y0, this.yF)) {
+          $("body").css("cursor", "progress");
           htrace.showSpanDetails(this.span);
+          $("body").css("cursor", "default");
         }
         return true;
     }
@@ -271,10 +273,12 @@
       y0: this.y0 + 2,
       yF: this.yF - 2,
       callback: function(e) {
+        $("body").css("cursor", "progress");
         var depth = (e.raw.ctrlKey) ? 100 : 0;
         $.when(widget.span.reifyParentsRecursive(depth)).done(function(result) {
           console.log("reifyParentsRecursive(" + depth + "): result was '" +
               result + "'");
+          $("body").css("cursor", "default");
           if (result != "") {
             alert(result);
           } else {
@@ -294,10 +298,14 @@
       y0: this.y0 + 2,
       yF: this.yF - 2,
       callback: function(e) {
+        $("body").css("cursor", "progress");
+        var lim = Math.min(parseInt($("#children-lim").val()) || 50, 500);
+        $("#children-lim").val(lim.toString());
         var depth = (e.raw.ctrlKey) ? 100 : 0;
-        $.when(widget.span.reifyChildrenRecursive(depth)).done(function (result) {
+        $.when(widget.span.reifyChildrenRecursive(depth, lim)).done(function (result) {
           console.log("reifyChildrenRecursive(" + depth + "): result was '" +
               result + "'");
+          $("body").css("cursor", "default");
           if (result != "") {
             alert(result);
           } else {
diff --git a/htrace-webapp/src/main/webapp/index.html b/htrace-webapp/src/main/webapp/index.html
index 7f4a687..c8f2493 100644
--- a/htrace-webapp/src/main/webapp/index.html
+++ b/htrace-webapp/src/main/webapp/index.html
@@ -207,6 +207,27 @@
               </form>
             </div>
           </div>
+          <div class="panel panel-default">
+            <div class="panel-heading">
+              <h1 class="panel-title">Limits</h1>
+            </div style="border: 1px solid #000000;">
+            <div class="panel-body">
+              <div class="form-horizontal">
+                <div class="form-group">
+                  <label class="col-sm-8 control-label">Max search results</label>
+                  <div class="col-sm-4">
+                    <input type="text" class="form-control" id="search-lim" value="20"/>
+                  </div>
+                </div>
+                <div class="form-group">
+                  <label class="col-sm-8 control-label">Max child lookup</label>
+                  <div class="col-sm-4">
+                    <input type="text" class="form-control" id="children-lim" value="50"/>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
         </div>
         <div class="col-md-9" id="resultsView">
         </div>