Bug 689142 - Places telemetry gets lost, due to being collected on idle-daily.

r=taras,dietrich
This commit is contained in:
Marco Bonardo 2011-10-07 21:10:42 +02:00
Родитель 13d317f8cb
Коммит 486891d3b2
6 изменённых файлов: 75 добавлений и 10 удалений

Просмотреть файл

@ -43,10 +43,20 @@
const Cc = Components.classes; const Cc = Components.classes;
const Ci = Components.interfaces; const Ci = Components.interfaces;
// Fired by TelemetryPing when async telemetry data should be collected.
const TOPIC_GATHER_TELEMETRY = "gather-telemetry";
// Seconds between maintenance runs. // Seconds between maintenance runs.
const MAINTENANCE_INTERVAL_SECONDS = 7 * 86400; const MAINTENANCE_INTERVAL_SECONDS = 7 * 86400;
////////////////////////////////////////////////////////////////////////////////
//// Imports
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesDBUtils",
"resource://gre/modules/PlacesDBUtils.jsm");
/** /**
* This component can be used as a starter for modules that have to run when * This component can be used as a starter for modules that have to run when
@ -54,6 +64,8 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
*/ */
function PlacesCategoriesStarter() function PlacesCategoriesStarter()
{ {
Services.obs.addObserver(this, TOPIC_GATHER_TELEMETRY, false);
Services.obs.addObserver(this, PlacesUtils.TOPIC_SHUTDOWN, false);
} }
PlacesCategoriesStarter.prototype = { PlacesCategoriesStarter.prototype = {
@ -63,15 +75,22 @@ PlacesCategoriesStarter.prototype = {
observe: function PCS_observe(aSubject, aTopic, aData) observe: function PCS_observe(aSubject, aTopic, aData)
{ {
switch (aTopic) { switch (aTopic) {
case PlacesUtils.TOPIC_SHUTDOWN:
Services.obs.removeObserver(this, PlacesUtils.TOPIC_SHUTDOWN);
Services.obs.removeObserver(this, TOPIC_GATHER_TELEMETRY);
break;
case TOPIC_GATHER_TELEMETRY:
PlacesDBUtils.telemetry();
break;
case "idle-daily": case "idle-daily":
// Once a week run places.sqlite maintenance tasks. // Once a week run places.sqlite maintenance tasks.
let lastMaintenance = 0; let lastMaintenance = 0;
try { try {
lastMaintenance = Services.prefs.getIntPref("places.database.lastMaintenance"); lastMaintenance =
Services.prefs.getIntPref("places.database.lastMaintenance");
} catch (ex) {} } catch (ex) {}
let nowSeconds = parseInt(Date.now() / 1000); let nowSeconds = parseInt(Date.now() / 1000);
if (lastMaintenance < nowSeconds - MAINTENANCE_INTERVAL_SECONDS) { if (lastMaintenance < nowSeconds - MAINTENANCE_INTERVAL_SECONDS) {
Components.utils.import("resource://gre/modules/PlacesDBUtils.jsm");
PlacesDBUtils.maintenanceOnIdle(); PlacesDBUtils.maintenanceOnIdle();
} }
break; break;

Просмотреть файл

@ -54,6 +54,8 @@ let EXPORTED_SYMBOLS = [ "PlacesDBUtils" ];
const FINISHED_MAINTENANCE_TOPIC = "places-maintenance-finished"; const FINISHED_MAINTENANCE_TOPIC = "places-maintenance-finished";
const BYTES_PER_MEBIBYTE = 1048576;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//// Smart getters //// Smart getters
@ -115,7 +117,6 @@ let PlacesDBUtils = {
this.checkIntegrity this.checkIntegrity
, this.checkCoherence , this.checkCoherence
, this._refreshUI , this._refreshUI
, this._telemetry
]); ]);
tasks.callback = aCallback; tasks.callback = aCallback;
tasks.scope = aScope; tasks.scope = aScope;
@ -861,7 +862,7 @@ let PlacesDBUtils = {
* @param [optional] aTasks * @param [optional] aTasks
* Tasks object to execute. * Tasks object to execute.
*/ */
_telemetry: function PDBU__telemetry(aTasks) telemetry: function PDBU_telemetry(aTasks)
{ {
let tasks = new Tasks(aTasks); let tasks = new Tasks(aTasks);
@ -911,7 +912,7 @@ let PlacesDBUtils = {
let DBFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile); let DBFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
DBFile.append("places.sqlite"); DBFile.append("places.sqlite");
try { try {
return parseInt(DBFile.fileSize / 1024); return parseInt(DBFile.fileSize / BYTES_PER_MEBIBYTE);
} catch (ex) { } catch (ex) {
return 0; return 0;
} }
@ -921,7 +922,7 @@ let PlacesDBUtils = {
let DBFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile); let DBFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
DBFile.append("places.sqlite-wal"); DBFile.append("places.sqlite-wal");
try { try {
return parseInt(DBFile.fileSize / 1024); return parseInt(DBFile.fileSize / BYTES_PER_MEBIBYTE);
} catch (ex) { } catch (ex) {
return 0; return 0;
} }

Просмотреть файл

@ -64,8 +64,10 @@ function run_test() {
PlacesUtils.tagging.tagURI(uri, ["tag"]); PlacesUtils.tagging.tagURI(uri, ["tag"]);
PlacesUtils.bookmarks.setKeywordForBookmark(itemId, "keyword"); PlacesUtils.bookmarks.setKeywordForBookmark(itemId, "keyword");
// Test generic database probes. // Request to gather telemetry data.
PlacesDBUtils._telemetry(); Cc["@mozilla.org/places/categoriesStarter;1"]
.getService(Ci.nsIObserver)
.observe(null, "gather-telemetry", null);
waitForAsyncUpdates(continue_test); waitForAsyncUpdates(continue_test);
} }

Просмотреть файл

@ -62,6 +62,10 @@ const MEM_HISTOGRAMS = {
"heap-allocated": "MEMORY_HEAP_ALLOCATED", "heap-allocated": "MEMORY_HEAP_ALLOCATED",
"page-faults-hard": "PAGE_FAULTS_HARD" "page-faults-hard": "PAGE_FAULTS_HARD"
}; };
// Seconds of idle time before pinging.
// On idle-daily a gather-telemetry notification is fired, during it probes can
// start asynchronous tasks to gather data. On the next idle the data is sent.
const IDLE_TIMEOUT_SECONDS = 5 * 60;
var gLastMemoryPoll = null; var gLastMemoryPoll = null;
@ -341,6 +345,10 @@ TelemetryPing.prototype = {
return; return;
Services.obs.removeObserver(this, "idle-daily"); Services.obs.removeObserver(this, "idle-daily");
Services.obs.removeObserver(this, "cycle-collector-begin"); Services.obs.removeObserver(this, "cycle-collector-begin");
if (this._isIdleObserver) {
idle.removeIdleObserver(this, IDLE_TIMEOUT_SECONDS);
this._isIdleObserver = false;
}
}, },
/** /**
@ -416,11 +424,26 @@ TelemetryPing.prototype = {
this.attachObservers() this.attachObservers()
} }
break; break;
case "idle-daily":
// Enqueue to main-thread, otherwise components may be inited by the
// idle-daily category and miss the gather-telemetry notification.
Services.tm.mainThread.dispatch((function() {
// Notify that data should be gathered now, since ping will happen soon.
Services.obs.notifyObservers(null, "gather-telemetry", null);
// The ping happens at the first idle of length IDLE_TIMEOUT_SECONDS.
idle.addIdleObserver(this, IDLE_TIMEOUT_SECONDS);
this._isIdleObserver = true;
}).bind(this), Ci.nsIThread.DISPATCH_NORMAL);
break;
case "test-ping": case "test-ping":
server = aData; server = aData;
// fall through // fall through
case "idle-daily": case "idle":
this.send(aTopic, server); if (this._isIdleObserver) {
idle.removeIdleObserver(this, IDLE_TIMEOUT_SECONDS);
this._isIdleObserver = false;
}
this.send(aTopic == "idle" ? "idle-daily" : aTopic, server);
break; break;
} }
}, },

Просмотреть файл

@ -0,0 +1,19 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Check that TelemetryPing notifies correctly on idle.
Components.utils.import("resource://gre/modules/Services.jsm");
function run_test() {
do_test_pending();
Services.obs.addObserver(function observeTelemetry() {
Services.obs.removeObserver(observeTelemetry, "gather-telemetry");
do_test_finished();
}, "gather-telemetry", false);
Components.classes["@mozilla.org/base/telemetry-ping;1"]
.getService(Components.interfaces.nsIObserver)
.observe(null, "idle-daily", null);
}

Просмотреть файл

@ -6,3 +6,4 @@ tail =
[test_TelemetryPing.js] [test_TelemetryPing.js]
# Bug 676989: test fails consistently on Android # Bug 676989: test fails consistently on Android
# fail-if = os == "android" # fail-if = os == "android"
[test_TelemetryPing_idle.js]