Skip to content

Commit

Permalink
[file-search] handle cancellation properly to avoid race conditions #…
Browse files Browse the repository at this point in the history
…4537

Signed-off-by: Anton Kosyakov <anton.kosyakov@typefox.io>
  • Loading branch information
akosyakov committed Mar 13, 2019
1 parent 029c7d2 commit b45ba43
Showing 1 changed file with 35 additions and 23 deletions.
58 changes: 35 additions & 23 deletions packages/file-search/src/browser/quick-file-open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,52 +137,64 @@ export class QuickFileOpenService implements QuickOpenModel, QuickOpenHandler {
private cancelIndicator = new CancellationTokenSource();

public async onType(lookFor: string, acceptor: (items: QuickOpenItem[]) => void): Promise<void> {
this.cancelIndicator.cancel();
this.cancelIndicator = new CancellationTokenSource();
const token = this.cancelIndicator.token;

const roots = this.workspaceService.tryGetRoots();
if (roots.length === 0) {
return;
}

this.currentLookFor = lookFor;
this.cancelIndicator.cancel();
this.cancelIndicator = new CancellationTokenSource();

const token = this.cancelIndicator.token;
const alreadyCollected = new Set<string>();
const recentlyUsedItems: QuickOpenItem[] = [];

const locations = [...this.navigationLocationService.locations()].reverse();
for (const location of locations) {
const uriString = location.uri.toString();
if (location.uri.scheme === 'file' && !alreadyCollected.has(uriString) && fuzzy.test(lookFor, uriString)) {
recentlyUsedItems.push(await this.toItem(location.uri, { groupLabel: recentlyUsedItems.length === 0 ? 'recently opened' : undefined, showBorder: false }));
const item = await this.toItem(location.uri, { groupLabel: recentlyUsedItems.length === 0 ? 'recently opened' : undefined, showBorder: false });
if (token.isCancellationRequested) {
return;
}
recentlyUsedItems.push(item);
alreadyCollected.add(uriString);
}
}
if (lookFor.length > 0) {
const handler = async (results: string[]) => {
if (!token.isCancellationRequested) {
const fileSearchResultItems: QuickOpenItem[] = [];
for (const fileUri of results) {
if (!alreadyCollected.has(fileUri)) {
fileSearchResultItems.push(await this.toItem(fileUri));
alreadyCollected.add(fileUri);
if (token.isCancellationRequested) {
return;
}
const fileSearchResultItems: QuickOpenItem[] = [];
for (const fileUri of results) {
if (!alreadyCollected.has(fileUri)) {
const item = await this.toItem(fileUri);
if (token.isCancellationRequested) {
return;
}
fileSearchResultItems.push(item);
alreadyCollected.add(fileUri);
}
}

// Create a copy of the file search results and sort.
const sortedResults = fileSearchResultItems.slice();
sortedResults.sort((a, b) => this.compareItems(a, b));

// Extract the first element, and re-add it to the array with the group label.
const first = sortedResults[0];
sortedResults.shift();
if (first) {
sortedResults.unshift(await this.toItem(first.getUri()!, { groupLabel: 'file results', showBorder: true }));
// Create a copy of the file search results and sort.
const sortedResults = fileSearchResultItems.slice();
sortedResults.sort((a, b) => this.compareItems(a, b));

// Extract the first element, and re-add it to the array with the group label.
const first = sortedResults[0];
sortedResults.shift();
if (first) {
const item = await this.toItem(first.getUri()!, { groupLabel: 'file results', showBorder: true });
if (token.isCancellationRequested) {
return;
}

// Return the recently used items, followed by the search results.
acceptor([...recentlyUsedItems, ...sortedResults]);
sortedResults.unshift(item);
}
// Return the recently used items, followed by the search results.
acceptor([...recentlyUsedItems, ...sortedResults]);
};
this.fileSearchService.find(lookFor, {
rootUris: roots.map(r => r.uri),
Expand Down

0 comments on commit b45ba43

Please sign in to comment.