Bug 819945 - Global searches choke when a source takes too long to fetch, r=past

This commit is contained in:
Victor Porof 2012-12-20 20:00:34 +02:00
parent 1d6ce59e77
commit 143216db06
2 changed files with 42 additions and 11 deletions

View File

@ -11,6 +11,7 @@ const Cu = Components.utils;
const DBG_STRINGS_URI = "chrome://browser/locale/devtools/debugger.properties";
const NEW_SCRIPT_DISPLAY_DELAY = 200; // ms
const FETCH_SOURCE_RESPONSE_DELAY = 50; // ms
const FRAME_STEP_CLEAR_DELAY = 100; // ms
const CALL_STACK_PAGE_SIZE = 25; // frames
@ -1178,16 +1179,26 @@ SourceScripts.prototype = {
* The source object coming from the active thread.
* @param function aCallback
* Function called after the source text has been loaded.
* @param function aOnTimeout
* Function called when the source text takes too long to fetch.
*/
getText: function SS_getText(aSource, aCallback) {
getText: function SS_getText(aSource, aCallback, aOnTimeout) {
// If already loaded, return the source text immediately.
if (aSource.loaded) {
aCallback(aSource.url, aSource.text);
return;
}
// If the source text takes too long to fetch, invoke a timeout to
// avoid blocking any operations.
if (aOnTimeout) {
var fetchTimeout = window.setTimeout(aOnTimeout, FETCH_SOURCE_RESPONSE_DELAY);
}
// Get the source text from the active thread.
this.activeThread.source(aSource.source).source(function(aResponse) {
window.clearTimeout(fetchTimeout);
if (aResponse.error) {
Cu.reportError("Error loading " + aSource.url + "\n" + aResponse.error);
aCallback(aSource.url, "");

View File

@ -1260,6 +1260,7 @@ function GlobalSearchView() {
MenuContainer.call(this);
this._startSearch = this._startSearch.bind(this);
this._onFetchSourceFinished = this._onFetchSourceFinished.bind(this);
this._onFetchSourceTimeout = this._onFetchSourceTimeout.bind(this);
this._onFetchSourcesFinished = this._onFetchSourcesFinished.bind(this);
this._createItemView = this._createItemView.bind(this);
this._onScroll = this._onScroll.bind(this);
@ -1402,25 +1403,29 @@ create({ constructor: GlobalSearchView, proto: MenuContainer.prototype }, {
this._sourcesCount = locations.length;
this._searchedToken = aQuery;
this._fetchSources(
this._onFetchSourceFinished,
this._onFetchSourcesFinished, locations);
this._fetchSources(locations, {
onFetch: this._onFetchSourceFinished,
onTimeout: this._onFetchSourceTimeout,
onFinished: this._onFetchSourcesFinished
});
},
/**
* Starts fetching all the sources, silently.
*
* @param function aFetchCallback
* Called after each source is fetched.
* @param function aFetchedCallback
* Called if all the sources were already fetched.
* @param array aLocations
* The locations for the sources to fetch.
* @param object aCallbacks
* An object containing the callback functions to invoke:
* - onFetch: called after each source is fetched
* - onTimeout: called when a source's text takes too long to fetch
* - onFinished: called if all the sources were already fetched
*/
_fetchSources: function DVGS__fetchSources(aFetchCallback, aFetchedCallback, aLocations) {
_fetchSources:
function DVGS__fetchSources(aLocations, { onFetch, onTimeout, onFinished }) {
// If all the sources were already fetched, then don't do anything.
if (this._cache.size == aLocations.length) {
aFetchedCallback();
onFinished();
return;
}
@ -1430,7 +1435,8 @@ create({ constructor: GlobalSearchView, proto: MenuContainer.prototype }, {
continue;
}
let sourceItem = DebuggerView.Sources.getItemByValue(location);
DebuggerController.SourceScripts.getText(sourceItem.attachment, aFetchCallback);
let sourceObject = sourceItem.attachment;
DebuggerController.SourceScripts.getText(sourceObject, onFetch, onTimeout);
}
},
@ -1452,10 +1458,24 @@ create({ constructor: GlobalSearchView, proto: MenuContainer.prototype }, {
}
},
/**
* Called when a source's text takes too long to fetch.
*/
_onFetchSourceTimeout: function DVGS__onFetchSourceTimeout() {
// Remove the source from the load queue.
this._sourcesCount--;
// Check if the remaining sources were fetched and stored in the cache.
if (this._cache.size == this._sourcesCount) {
this._onFetchSourcesFinished();
}
},
/**
* Called when all the sources have been fetched.
*/
_onFetchSourcesFinished: function DVGS__onFetchSourcesFinished() {
// At least one source needs to be present to perform a global search.
if (!this._sourcesCount) {
return;
}