Title: [172747] trunk/Tools
Revision
172747
Author
a...@apple.com
Date
2014-08-19 00:37:45 -0700 (Tue, 19 Aug 2014)

Log Message

build.webkit.org/dashboard should not request 50 revisions from trac each time
https://bugs.webkit.org/show_bug.cgi?id=127130

build.webkit.org/dashboard sometimes fetches a Trac revision in an intermediate state, and never updates later
https://bugs.webkit.org/show_bug.cgi?id=127131

Reviewed by Timothy Hatcher.

Turns out that requesting 50 builds is much slower than requesting by date - even
if the request ends up returning more than 50 results. There is no way to only
request updates, but this change brings request time from 6-8 seconds down to
less than a second.

This patch generalizes date handling for later use in metrics code. As part of the
rewrite, I made newly fetched data update author e-mail in previously fetched
revisions, as it changes after commit queue first lands.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueueView.js:
Updated for event rename. I changed the trac event to not contain the list of new
commits, as we now sometimes update old commits, and that couldn't be expressed
in event data. We never used the list anywhere in the first place.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Trac.js:
(Trac.prototype._xmlTimelineURL): Made this function take arbitrary dates. When called
without arguments, return commits for today and yesterday.
(Trac.prototype._loaded):
(Trac.prototype.update): Moved the function for processing loaded results out of
here for clarity, and also because I'm going to have a separate loading code path
for metrics.

Modified Paths

Diff

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueueView.js (172746 => 172747)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueueView.js	2014-08-19 07:14:30 UTC (rev 172746)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueueView.js	2014-08-19 07:37:45 UTC (rev 172747)
@@ -48,9 +48,9 @@
         queue.addEventListener(BuildbotQueue.Event.UnauthorizedAccess, this._unauthorizedAccess, this);
     }.bind(this));
 
-    webkitTrac.addEventListener(Trac.Event.NewCommitsRecorded, this._newCommitsRecorded, this);
+    webkitTrac.addEventListener(Trac.Event.CommitsUpdated, this._newCommitsRecorded, this);
     if (typeof internalTrac != "undefined")
-        internalTrac.addEventListener(Trac.Event.NewCommitsRecorded, this._newCommitsRecorded, this);
+        internalTrac.addEventListener(Trac.Event.CommitsUpdated, this._newCommitsRecorded, this);
 };
 
 BaseObject.addConstructorFunctions(BuildbotQueueView);

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Trac.js (172746 => 172747)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Trac.js	2014-08-19 07:14:30 UTC (rev 172746)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Trac.js	2014-08-19 07:37:45 UTC (rev 172747)
@@ -44,7 +44,7 @@
 Trac.UpdateInterval = 45000; // 45 seconds
 
 Trac.Event = {
-    NewCommitsRecorded: "new-commits-recorded"
+    CommitsUpdated: "commits-updated"
 };
 
 Trac.prototype = {
@@ -63,9 +63,24 @@
         return this.baseURL + "changeset/" + encodeURIComponent(revision);
     },
 
-    _xmlTimelineURL: function()
+    _xmlTimelineURL: function(fromDate, toDate)
     {
-        return this.baseURL + "timeline?changeset=on&max=50&format=rss";
+        if (typeof fromDate === "undefined") {
+            fromDate = new Date();
+            toDate = new Date(fromDate);
+            // By default, get at least one full day of changesets, as the current day may have only begun.
+            fromDate.setDate(fromDate.getDate() - 1);
+        } else if (typeof toDate === "undefined")
+            toDate = fromDate;
+
+        console.assert(fromDate <= toDate);
+
+        var fromDay = new Date(fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate());
+        var toDay = new Date(toDate.getFullYear(), toDate.getMonth(), toDate.getDate());
+
+        return this.baseURL + "timeline?changeset=on&format=rss&max=-1" +
+            "&from=" +  (toDay.getMonth() + 1) + "%2F" + toDay.getDate() + "%2F" + (toDay.getFullYear() % 100) +
+            "&daysback=" + ((toDay - fromDay) / 1000 / 60 / 60 / 24);
     },
 
     _convertCommitInfoElementToObject: function(doc, commitElement)
@@ -109,30 +124,63 @@
         };
     },
 
-    update: function()
+    _loaded: function(dataDocument)
     {
-        loadXML(this._xmlTimelineURL(), function(dataDocument) {
-            var latestKnownRevision = 0;
-            if (this.recordedCommits.length)
-                latestKnownRevision = this.recordedCommits[this.recordedCommits.length - 1].revisionNumber;
+        var earliestKnownRevision = 0;
+        var latestKnownRevision = 0;
+        if (this.recordedCommits.length) {
+            earliestKnownRevision = this.recordedCommits[0].revisionNumber;
+            latestKnownRevision = this.recordedCommits[this.recordedCommits.length - 1].revisionNumber;
+        }
 
-            var newCommits = [];
+        var knownCommitsWereUpdated = false;
+        var newCommits = [];
+        var newCommitsBeforeEarliestKnownRevision = [];
 
-            var commitInfoElements = dataDocument.evaluate("/rss/channel/item", dataDocument, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE);
-            var commitInfoElement = undefined;
-            while (commitInfoElement = commitInfoElements.iterateNext()) {
-                var commit = this._convertCommitInfoElementToObject(dataDocument, commitInfoElement);
-                if (commit.revisionNumber == latestKnownRevision)
-                    break;
+        var commitInfoElements = dataDocument.evaluate("/rss/channel/item", dataDocument, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE);
+        var commitInfoElement = undefined;
+        var indexInRecordedCommits = undefined;
+        while (commitInfoElement = commitInfoElements.iterateNext()) {
+            var commit = this._convertCommitInfoElementToObject(dataDocument, commitInfoElement);
+            if (commit.revisionNumber > latestKnownRevision) {
+                console.assert(typeof indexInRecordedCommits === "undefined");
                 newCommits.push(commit);
+            } else if (commit.revisionNumber < earliestKnownRevision) {
+                console.assert(typeof indexInRecordedCommits === "undefined" || indexInRecordedCommits === -1);
+                newCommitsBeforeEarliestKnownRevision.push(commit);
+            } else {
+                if (typeof indexInRecordedCommits === "undefined") {
+                    // We could have started anywhere in the recorded commits array, let's find where.
+                    // With periodic updates, this will be the latest recorded commit, so starting from the end.
+                    for (var i = this.recordedCommits.length - 1; i >= 0; --i) {
+                        if (this.recordedCommits[i].revisionNumber === commit.revisionNumber) {
+                            indexInRecordedCommits = i;
+                            break;
+                        }
+                    }
+                }
+
+                console.assert(indexInRecordedCommits >= 0);
+                console.assert(this.recordedCommits[indexInRecordedCommits].revisionNumber === commit.revisionNumber);
+
+                // Author could have changed, as commit queue replaces it after the fact.
+                if (this.recordedCommits[indexInRecordedCommits].author !== commit.author) {
+                    this.recordedCommits[indexInRecordedCommits].author = commit.author;
+                    knownCommitWasUpdated = true;
+                }
+                --indexInRecordedCommits;
             }
-            
-            if (!newCommits.length)
-                return;
+        }
 
-            this.recordedCommits = this.recordedCommits.concat(newCommits.reverse());
+        if (newCommits.length || newCommitsBeforeEarliestKnownRevision.length)
+            this.recordedCommits = newCommitsBeforeEarliestKnownRevision.reverse().concat(this.recordedCommits, newCommits.reverse());
 
-            this.dispatchEventToListeners(Trac.Event.NewCommitsRecorded, {newCommits: newCommits});
-        }.bind(this), this._needsAuthentication ? { withCredentials: true } : {});
+        if (newCommits.length || newCommitsBeforeEarliestKnownRevision.length || knownCommitsWereUpdated)
+            this.dispatchEventToListeners(Trac.Event.CommitsUpdated, null);
+    },
+
+    update: function()
+    {
+        loadXML(this._xmlTimelineURL(), this._loaded.bind(this), this._needsAuthentication ? { withCredentials: true } : {});
     }
 };

Modified: trunk/Tools/ChangeLog (172746 => 172747)


--- trunk/Tools/ChangeLog	2014-08-19 07:14:30 UTC (rev 172746)
+++ trunk/Tools/ChangeLog	2014-08-19 07:37:45 UTC (rev 172747)
@@ -1,3 +1,35 @@
+2014-08-19  Alexey Proskuryakov  <a...@apple.com>
+
+        build.webkit.org/dashboard should not request 50 revisions from trac each time
+        https://bugs.webkit.org/show_bug.cgi?id=127130
+
+        build.webkit.org/dashboard sometimes fetches a Trac revision in an intermediate state, and never updates later
+        https://bugs.webkit.org/show_bug.cgi?id=127131
+
+        Reviewed by Timothy Hatcher.
+
+        Turns out that requesting 50 builds is much slower than requesting by date - even
+        if the request ends up returning more than 50 results. There is no way to only
+        request updates, but this change brings request time from 6-8 seconds down to
+        less than a second.
+
+        This patch generalizes date handling for later use in metrics code. As part of the
+        rewrite, I made newly fetched data update author e-mail in previously fetched
+        revisions, as it changes after commit queue first lands.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueueView.js:
+        Updated for event rename. I changed the trac event to not contain the list of new
+        commits, as we now sometimes update old commits, and that couldn't be expressed
+        in event data. We never used the list anywhere in the first place.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/Trac.js:
+        (Trac.prototype._xmlTimelineURL): Made this function take arbitrary dates. When called
+        without arguments, return commits for today and yesterday.
+        (Trac.prototype._loaded):
+        (Trac.prototype.update): Moved the function for processing loaded results out of
+        here for clarity, and also because I'm going to have a separate loading code path
+        for metrics.
+
 2014-08-18  Dan Bernstein  <m...@apple.com>
 
         Added an update-webkit option to override the ../Internal check.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to