Defer metrics reporting until plugins are loaded
Cache all events reported via gr-reporting instances in closure in order to share the cahce. Flush the cache on next reporting after plugins are loaded. This allows plugins to receive all reporting events and unlocks Google Analytics integration. Change-Id: Ic0c1d37667208bfd55bbf77e2138d0170f7fb097
This commit is contained in:
@@ -15,6 +15,7 @@ limitations under the License.
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
|
||||
|
||||
<dom-module id="gr-reporting">
|
||||
<script src="gr-reporting.js"></script>
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
var CHANGE_VIEW_REGEX = /^\/c\/\d+\/?\d*$/;
|
||||
var DIFF_VIEW_REGEX = /^\/c\/\d+\/\d+\/.+$/;
|
||||
|
||||
var pending = [];
|
||||
|
||||
Polymer({
|
||||
is: 'gr-reporting',
|
||||
|
||||
@@ -40,7 +42,7 @@
|
||||
_baselines: {
|
||||
type: Array,
|
||||
value: function() { return {}; },
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
get performanceTiming() {
|
||||
@@ -51,8 +53,13 @@
|
||||
return Math.round(10 * window.performance.now()) / 10;
|
||||
},
|
||||
|
||||
reporter: function(type, category, eventName, eventValue) {
|
||||
eventValue = eventValue;
|
||||
reporter: function() {
|
||||
var report = (Gerrit._arePluginsLoaded() && !pending.length) ?
|
||||
this.defaultReporter : this.cachingReporter;
|
||||
report.apply(this, arguments);
|
||||
},
|
||||
|
||||
defaultReporter: function(type, category, eventName, eventValue) {
|
||||
var detail = {
|
||||
type: type,
|
||||
category: category,
|
||||
@@ -63,6 +70,19 @@
|
||||
console.log(eventName + ': ' + eventValue);
|
||||
},
|
||||
|
||||
cachingReporter: function(type, category, eventName, eventValue) {
|
||||
if (Gerrit._arePluginsLoaded()) {
|
||||
if (pending.length) {
|
||||
pending.splice(0).forEach(function(args) {
|
||||
this.reporter.apply(this, args);
|
||||
}, this);
|
||||
}
|
||||
this.reporter(type, category, eventName, eventValue);
|
||||
} else {
|
||||
pending.push([type, category, eventName, eventValue]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* User-perceived app start time, should be reported when the app is ready.
|
||||
*/
|
||||
@@ -105,6 +125,10 @@
|
||||
NAVIGATION.TYPE, NAVIGATION.CATEGORY, NAVIGATION.PAGE, page);
|
||||
},
|
||||
|
||||
pluginsLoaded: function() {
|
||||
this.timeEnd('PluginsLoaded');
|
||||
},
|
||||
|
||||
_getPathname: function() {
|
||||
return window.location.pathname;
|
||||
},
|
||||
|
||||
@@ -90,6 +90,48 @@ limitations under the License.
|
||||
));
|
||||
});
|
||||
|
||||
suite('plugins', function() {
|
||||
setup(function() {
|
||||
element.reporter.restore();
|
||||
sandbox.stub(element, 'defaultReporter');
|
||||
sandbox.stub(Gerrit, '_arePluginsLoaded');
|
||||
});
|
||||
|
||||
test('pluginsLoaded reports time', function() {
|
||||
Gerrit._arePluginsLoaded.returns(true);
|
||||
var nowStub = sinon.stub(element, 'now').returns(42);
|
||||
element.pluginsLoaded();
|
||||
assert.isTrue(element.defaultReporter.calledWithExactly(
|
||||
'timing-report', 'UI Latency', 'PluginsLoaded', 42
|
||||
));
|
||||
});
|
||||
|
||||
test('caches reports if plugins are not loaded', function() {
|
||||
Gerrit._arePluginsLoaded.returns(false);
|
||||
element.timeEnd('foo');
|
||||
assert.isFalse(element.defaultReporter.called);
|
||||
});
|
||||
|
||||
test('reports if plugins are loaded', function() {
|
||||
Gerrit._arePluginsLoaded.returns(true);
|
||||
element.timeEnd('foo');
|
||||
assert.isTrue(element.defaultReporter.called);
|
||||
});
|
||||
|
||||
test('reports cached events preserving order', function() {
|
||||
Gerrit._arePluginsLoaded.returns(false);
|
||||
element.timeEnd('foo');
|
||||
Gerrit._arePluginsLoaded.returns(true);
|
||||
element.timeEnd('bar');
|
||||
assert.isTrue(element.defaultReporter.firstCall.calledWith(
|
||||
'timing-report', 'UI Latency', 'foo'
|
||||
));
|
||||
assert.isTrue(element.defaultReporter.secondCall.calledWith(
|
||||
'timing-report', 'UI Latency', 'bar'
|
||||
));
|
||||
});
|
||||
});
|
||||
|
||||
suite('location changed', function() {
|
||||
var pathnameStub;
|
||||
setup(function() {
|
||||
|
||||
@@ -110,10 +110,12 @@
|
||||
},
|
||||
|
||||
_loadPlugins: function(plugins) {
|
||||
Gerrit._setPluginsCount(plugins.length);
|
||||
for (var i = 0; i < plugins.length; i++) {
|
||||
var scriptEl = document.createElement('script');
|
||||
scriptEl.defer = true;
|
||||
scriptEl.src = '/' + plugins[i];
|
||||
scriptEl.onerror = Gerrit._pluginInstalled;
|
||||
document.body.appendChild(scriptEl);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -78,5 +78,11 @@ limitations under the License.
|
||||
assert.equal(gwtLink.href,
|
||||
'http://' + location.host + '/?polygerrit=0#/c/1/1/testfile.txt@2');
|
||||
});
|
||||
|
||||
test('sets plugins count', function() {
|
||||
sandbox.stub(Gerrit, '_setPluginsCount');
|
||||
element._loadPlugins([]);
|
||||
assert.isTrue(Gerrit._setPluginsCount.calledWithExactly(0));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
|
||||
<link rel="import" href="../gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
|
||||
<dom-module id="gr-js-api-interface">
|
||||
@@ -23,4 +24,3 @@ limitations under the License.
|
||||
<script src="gr-js-api-interface.js"></script>
|
||||
<script src="gr-public-js-api.js"></script>
|
||||
</dom-module>
|
||||
|
||||
|
||||
@@ -172,5 +172,49 @@ limitations under the License.
|
||||
});
|
||||
});
|
||||
|
||||
test('_setPluginsCount', function(done) {
|
||||
stub('gr-reporting', {
|
||||
pluginsLoaded: function() {
|
||||
assert.equal(Gerrit._pluginsPending, 0);
|
||||
done();
|
||||
}
|
||||
});
|
||||
Gerrit._setPluginsCount(0);
|
||||
});
|
||||
|
||||
test('_arePluginsLoaded', function() {
|
||||
assert.isFalse(Gerrit._arePluginsLoaded());
|
||||
Gerrit._setPluginsCount(1);
|
||||
assert.isFalse(Gerrit._arePluginsLoaded());
|
||||
Gerrit._setPluginsCount(0);
|
||||
assert.isTrue(Gerrit._arePluginsLoaded());
|
||||
});
|
||||
|
||||
test('_pluginInstalled', function(done) {
|
||||
stub('gr-reporting', {
|
||||
pluginsLoaded: function() {
|
||||
done();
|
||||
}
|
||||
});
|
||||
Gerrit._setPluginsCount(2);
|
||||
Gerrit._pluginInstalled();
|
||||
assert.equal(Gerrit._pluginsPending, 1);
|
||||
Gerrit._pluginInstalled();
|
||||
});
|
||||
|
||||
test('install calls _pluginInstalled', function() {
|
||||
var stub = sinon.stub(Gerrit, '_pluginInstalled');
|
||||
Gerrit.install(function(p) { plugin = p; }, '0.1',
|
||||
'http://test.com/plugins/testplugin/static/test.js');
|
||||
assert.isTrue(stub.calledOnce);
|
||||
stub.restore();
|
||||
});
|
||||
|
||||
test('install calls _pluginInstalled on error', function() {
|
||||
var stub = sinon.stub(Gerrit, '_pluginInstalled');
|
||||
Gerrit.install(function() {}, '0.0pre-alpha');
|
||||
assert.isTrue(stub.calledOnce);
|
||||
stub.restore();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -64,6 +64,9 @@
|
||||
|
||||
var Gerrit = window.Gerrit || {};
|
||||
|
||||
// Number of plugins to initialize, -1 means 'not yet known'.
|
||||
Gerrit._pluginsPending = -1;
|
||||
|
||||
Gerrit.getPluginName = function() {
|
||||
console.warn('Gerrit.getPluginName is not supported in PolyGerrit.',
|
||||
'Please use self.getPluginName() instead.');
|
||||
@@ -85,12 +88,14 @@
|
||||
if (opt_version && opt_version !== API_VERSION) {
|
||||
console.warn('Only version ' + API_VERSION +
|
||||
' is supported in PolyGerrit. ' + opt_version + ' was given.');
|
||||
Gerrit._pluginInstalled();
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(andybons): Polyfill currentScript for IE10/11 (edge supports it).
|
||||
var src = opt_src || (document.currentScript && document.currentScript.src);
|
||||
callback(new Plugin(src));
|
||||
Gerrit._pluginInstalled();
|
||||
};
|
||||
|
||||
Gerrit.getLoggedIn = function() {
|
||||
@@ -101,5 +106,20 @@
|
||||
// NOOP since PolyGerrit doesn’t support GWT plugins.
|
||||
};
|
||||
|
||||
Gerrit._setPluginsCount = function(count) {
|
||||
Gerrit._pluginsPending = count;
|
||||
if (Gerrit._arePluginsLoaded()) {
|
||||
document.createElement('gr-reporting').pluginsLoaded();
|
||||
}
|
||||
};
|
||||
|
||||
Gerrit._pluginInstalled = function() {
|
||||
Gerrit._setPluginsCount(Gerrit._pluginsPending - 1);
|
||||
};
|
||||
|
||||
Gerrit._arePluginsLoaded = function() {
|
||||
return Gerrit._pluginsPending === 0;
|
||||
};
|
||||
|
||||
window.Gerrit = Gerrit;
|
||||
})(window);
|
||||
|
||||
Reference in New Issue
Block a user