From 842c7928687fe6d08d11856efd60c271fc096dad Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 4 Nov 2013 14:47:13 -0500 Subject: [PATCH] search: Only do a subsearch if the previous results have returned from DBus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- js/ui/search.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/js/ui/search.js b/js/ui/search.js index 4bde7fcba..50868e386 100644 --- a/js/ui/search.js +++ b/js/ui/search.js @@ -110,16 +110,13 @@ const SearchSystem = new Lang.Class({ this._terms = terms; - if (isSubSearch) { - this._providers.forEach(Lang.bind(this, function(provider) { - let previousProviderResults = previousResults[provider.id]; + this._providers.forEach(Lang.bind(this, function(provider) { + let previousProviderResults = previousResults[provider.id]; + if (isSubSearch && previousProviderResults) provider.getSubsearchResultSet(previousProviderResults, terms, Lang.bind(this, this._gotResults, provider), this._cancellable); - })); - } else { - this._providers.forEach(Lang.bind(this, function(provider) { + else provider.getInitialResultSet(terms, Lang.bind(this, this._gotResults, provider), this._cancellable); - })); - } + })); } }); Signals.addSignalMethods(SearchSystem.prototype);