search: Only do a subsearch if the previous results have returned from DBus

There's a potential race condition in the search code: if we have an
outstanding search call to a provider for search "A", and if before it comes
back we do a subsearch for "AB", we won't have any results to pass along.

Previously, we used an empty list when storing the provider results, so we
effectively told the remote search app to filter through this empty list for
any search results that meet the new query, meaning we showed the user 0
results for the provider in this case.

Now that we don't store an empty list, but instead store `undefined`, this race
raises a warning. Solve it by doing an initial search query in this case
instead.

The search code isn't too smart about chained subsearches: now, if we hit this
race while already on a subsearch, we'll do an initial search for the subsearch
query instead, but that is much better than showing the user nothing. This
could be fixed in the future for a performance improvement.

Reviewed-by: Florian Müllner <fmuellner@gnome.org>
This commit is contained in:
Jasper St. Pierre 2013-11-04 14:47:13 -05:00
parent 4ba8518462
commit 842c792868

View File

@ -110,17 +110,14 @@ const SearchSystem = new Lang.Class({
this._terms = terms; this._terms = terms;
if (isSubSearch) {
this._providers.forEach(Lang.bind(this, function(provider) { this._providers.forEach(Lang.bind(this, function(provider) {
let previousProviderResults = previousResults[provider.id]; let previousProviderResults = previousResults[provider.id];
if (isSubSearch && previousProviderResults)
provider.getSubsearchResultSet(previousProviderResults, terms, Lang.bind(this, this._gotResults, provider), this._cancellable); provider.getSubsearchResultSet(previousProviderResults, terms, Lang.bind(this, this._gotResults, provider), this._cancellable);
})); else
} else {
this._providers.forEach(Lang.bind(this, function(provider) {
provider.getInitialResultSet(terms, Lang.bind(this, this._gotResults, provider), this._cancellable); provider.getInitialResultSet(terms, Lang.bind(this, this._gotResults, provider), this._cancellable);
})); }));
} }
}
}); });
Signals.addSignalMethods(SearchSystem.prototype); Signals.addSignalMethods(SearchSystem.prototype);