New perf dashboard UI tries to fetch commits all the time
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Oct 2014 03:45:20 +0000 (03:45 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Oct 2014 03:45:20 +0000 (03:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=137592

Reviewed by Andreas Kling.

Added hasReportedCommits boolean to repository meta data in manifest.json, and used that in
the front end to avoid issuing HTTP requests to fetch commit logs for repositories with
no reported commits as they are all going to fail.

Also added an internal cache to FetchCommitsForTimeRange in the front end to avoid fetching
the same commit logs repeatedly. There are two data structures we cache: commitsByRevision
which maps a given commit revision/hash to a commit object; and commitsByTime which is an array
of commits sorted chronologically by time.

* public/include/manifest.php:

* public/v2/app.js:
(App.CommitsViewerComponent.commitsChanged):

* public/v2/data.js:
(FetchCommitsForTimeRange):
(FetchCommitsForTimeRange._cachedCommitsByRepository):

* public/v2/manifest.js:
(App.Repository):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@174555 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Websites/perf.webkit.org/ChangeLog
Websites/perf.webkit.org/public/include/manifest.php
Websites/perf.webkit.org/public/v2/app.js
Websites/perf.webkit.org/public/v2/data.js
Websites/perf.webkit.org/public/v2/manifest.js

index fe6b755028b9c2888299fd2a0531f84d06bd011e..b5156b9ec7d2c86bde121a253d6fc427af567cda 100644 (file)
@@ -1,3 +1,31 @@
+2014-10-09  Ryosuke Niwa  <rniwa@webkit.org>
+
+        New perf dashboard UI tries to fetch commits all the time
+        https://bugs.webkit.org/show_bug.cgi?id=137592
+
+        Reviewed by Andreas Kling.
+
+        Added hasReportedCommits boolean to repository meta data in manifest.json, and used that in
+        the front end to avoid issuing HTTP requests to fetch commit logs for repositories with
+        no reported commits as they are all going to fail.
+
+        Also added an internal cache to FetchCommitsForTimeRange in the front end to avoid fetching
+        the same commit logs repeatedly. There are two data structures we cache: commitsByRevision
+        which maps a given commit revision/hash to a commit object; and commitsByTime which is an array
+        of commits sorted chronologically by time.
+
+        * public/include/manifest.php:
+
+        * public/v2/app.js:
+        (App.CommitsViewerComponent.commitsChanged):
+
+        * public/v2/data.js:
+        (FetchCommitsForTimeRange):
+        (FetchCommitsForTimeRange._cachedCommitsByRepository):
+
+        * public/v2/manifest.js:
+        (App.Repository):
+
 2014-10-08  Ryosuke Niwa  <rniwa@webkit.org>
 
         Another unreviewed build fix after r174477.
index 1c7e4f35263c6385df183e05f5f510572b22f2be..c91cb1d8747945f5f03c39c214349a2f95649814 100644 (file)
@@ -15,12 +15,18 @@ class ManifestGenerator {
         $config_table = $this->db->fetch_table('test_configurations');
         $platform_table = $this->db->fetch_table('platforms');
         $repositories_table = $this->db->fetch_table('repositories');
+
+        $repositories_with_commit = $this->db->query_and_fetch_all(
+            'SELECT DISTINCT(commit_repository) FROM commits WHERE commit_reported IS TRUE') or array();
+        foreach ($repositories_with_commit as &$row)
+            $row = $row['commit_repository'];
+
         $this->manifest = array(
             'tests' => $this->tests(),
             'metrics' => $this->metrics(),
             'all' => $this->platforms($config_table, $platform_table, false),
             'dashboard' => $this->platforms($config_table, $platform_table, true),
-            'repositories' => $this->repositories($repositories_table),
+            'repositories' => $this->repositories($repositories_table, $repositories_with_commit),
             'builders' => $this->builders(),
             'bugTrackers' => $this->bug_trackers($repositories_table),
         );
@@ -85,12 +91,16 @@ class ManifestGenerator {
         return $platforms;
     }
 
-    private function repositories($repositories_table) {
+    private function repositories($repositories_table, $repositories_with_commit) {
         $repositories = array();
         if (!$repositories_table)
             return $repositories;
-        foreach ($repositories_table as $row)
-            $repositories[$row['repository_name']] = array('url' => $row['repository_url'], 'blameUrl' => $row['repository_blame_url']);
+        foreach ($repositories_table as $row) {
+            $repositories[$row['repository_name']] = array(
+                'url' => $row['repository_url'],
+                'blameUrl' => $row['repository_blame_url'],
+                'hasReportedCommits' => in_array($row['repository_id'], $repositories_with_commit));
+        }
 
         return $repositories;
     }
index c46bacc9093c3d16b345611ae68771c9cba65cea..f48ed4cdc1163327b59fa63b6287c29ac6c5aed7 100755 (executable)
@@ -1408,7 +1408,7 @@ App.CommitsViewerComponent = Ember.Component.extend({
         var to = revisionInfo.get('currentRevision');
         var from = revisionInfo.get('previousRevision') || to;
         var repository = this.get('repository');
-        if (!from || !repository)
+        if (!from || !repository || !repository.get('hasReportedCommits'))
             return;
 
         var self = this;
index ad02b379c74df68750474b72468569943353d64a..32d52f22447c6c17a44db204f52e95eac72c85af 100755 (executable)
@@ -1,15 +1,44 @@
 // We don't use DS.Model for these object types because we can't afford to process millions of them.
 
-FetchCommitsForTimeRange = function (repository, from, to)
+function FetchCommitsForTimeRange(repository, from, to)
 {
     var url = '../api/commits/' + repository.get('id') + '/' + from + '-' + to;
-    console.log('Fetching ' + url)
+
+    var cachedCommits = FetchCommitsForTimeRange._cachedCommitsByRepository[repository];
+    if (!cachedCommits) {
+        cachedCommits = {commitsByRevision: {}, commitsByTime: []};
+        FetchCommitsForTimeRange._cachedCommitsByRepository[repository] = cachedCommits;
+    }
+
+    if (cachedCommits) {
+        var startCommit = cachedCommits.commitsByRevision[from];
+        var endCommit = cachedCommits.commitsByRevision[to];
+        if (startCommit && endCommit) {
+            return new Ember.RSVP.Promise(function (resolve) {
+                resolve(cachedCommits.commitsByTime.slice(startCommit.index, endCommit.index + 1)) });
+        }
+    }
+
+    console.log('Fecthing ' + url);
+
     return new Ember.RSVP.Promise(function (resolve, reject) {
         $.getJSON(url, function (data) {
             if (data.status != 'OK') {
                 reject(data.status);
                 return;
             }
+
+            data.commits.forEach(function (commit) {
+                if (cachedCommits.commitsByRevision[commit.revision])
+                    return;
+                commit.time = new Date(commit.time.replace(' ', 'T'));
+                cachedCommits.commitsByRevision[commit.revision] = commit;
+                cachedCommits.commitsByTime.push(commit);
+            });
+
+            cachedCommits.commitsByTime.sort(function (a, b) { return a.time - b.time; });
+            cachedCommits.commitsByTime.forEach(function (commit, index) { commit.index = index; });
+
             resolve(data.commits);
         }).fail(function (xhr, status, error) {
             reject(xhr.status + (error ? ', ' + error : ''));
@@ -17,6 +46,8 @@ FetchCommitsForTimeRange = function (repository, from, to)
     });
 }
 
+FetchCommitsForTimeRange._cachedCommitsByRepository = {};
+
 function Measurement(rawData)
 {
     this._raw = rawData;
index 6283a5808e708f5be5091db7c0749a7a81bf1cb2..b10c0be29a1659209cc3c9188c7fbaff039c3ccf 100755 (executable)
@@ -72,6 +72,7 @@ App.Platform = App.NameLabelModel.extend({
 App.Repository = App.NameLabelModel.extend({
     url: DS.attr('string'),
     blameUrl: DS.attr('string'),
+    hasReportedCommits: DS.attr('boolean'),
     urlForRevision: function (currentRevision) {
         return (this.get('url') || '').replace(/\$1/g, currentRevision);
     },