diff --git a/src/vs/workbench/services/search/node/textSearch.ts b/src/vs/workbench/services/search/node/textSearch.ts index f6e2109a392..65ef0a1121b 100644 --- a/src/vs/workbench/services/search/node/textSearch.ts +++ b/src/vs/workbench/services/search/node/textSearch.ts @@ -12,7 +12,7 @@ import { IProgress } from 'vs/platform/search/common/search'; import { FileWalker } from 'vs/workbench/services/search/node/fileSearch'; import { ISerializedFileMatch, ISerializedSearchComplete, IRawSearch, ISearchEngine } from './search'; -import { ISearchWorker, ISearchWorkerConfig } from './worker/searchWorkerIpc'; +import { ISearchWorker } from './worker/searchWorkerIpc'; import { ITextSearchWorkerProvider } from './textSearchWorkerProvider'; export class Engine implements ISearchEngine { @@ -55,8 +55,7 @@ export class Engine implements ISearchEngine { initializeWorkers(): void { this.workers.forEach(w => { - const config: ISearchWorkerConfig = { pattern: this.config.contentPattern, fileEncoding: this.config.fileEncoding }; - w.initialize(config) + w.initialize() .then(null, onUnexpectedError); }); } @@ -94,7 +93,8 @@ export class Engine implements ISearchEngine { this.nextWorker = (this.nextWorker + 1) % this.workers.length; const maxResults = this.config.maxResults && (this.config.maxResults - this.numResults); - worker.search({ absolutePaths: batch, maxResults }).then(result => { + const searchArgs = { absolutePaths: batch, maxResults, pattern: this.config.contentPattern, fileEncoding: this.config.fileEncoding }; + worker.search(searchArgs).then(result => { if (!result || this.limitReached || this.isCanceled) { return unwind(batchBytes); } diff --git a/src/vs/workbench/services/search/node/worker/searchWorker.ts b/src/vs/workbench/services/search/node/worker/searchWorker.ts index 122048e44c8..257899996ff 100644 --- a/src/vs/workbench/services/search/node/worker/searchWorker.ts +++ b/src/vs/workbench/services/search/node/worker/searchWorker.ts @@ -18,7 +18,7 @@ import { ILineMatch } from 'vs/platform/search/common/search'; import { UTF16le, UTF16be, UTF8, UTF8_with_bom, encodingExists, decode } from 'vs/base/node/encoding'; import { detectMimeAndEncodingFromBuffer } from 'vs/base/node/mime'; -import { ISearchWorker, ISearchWorkerConfig, ISearchWorkerSearchArgs, ISearchWorkerSearchResult } from './searchWorkerIpc'; +import { ISearchWorker, ISearchWorkerSearchArgs, ISearchWorkerSearchResult } from './searchWorkerIpc'; interface ReadLinesOptions { bufferLength: number; @@ -36,20 +36,24 @@ function onError(error: any): void { export class SearchWorkerManager implements ISearchWorker { private currentSearchEngine: SearchWorkerEngine; - initialize(config: ISearchWorkerConfig): TPromise { - this.currentSearchEngine = new SearchWorkerEngine(config); + initialize(): TPromise { + this.currentSearchEngine = new SearchWorkerEngine(); return TPromise.wrap(undefined); } cancel(): TPromise { // Cancel the current search. It will stop searching and close its open files. - this.currentSearchEngine.cancel(); + if (this.currentSearchEngine) { + this.currentSearchEngine.cancel(); + } + return TPromise.wrap(null); } search(args: ISearchWorkerSearchArgs): TPromise { if (!this.currentSearchEngine) { - return TPromise.wrapError(new Error('SearchWorker is not initialized')); + // Worker timed out during search + this.initialize(); } return this.currentSearchEngine.searchBatch(args); @@ -63,27 +67,21 @@ interface IFileSearchResult { } export class SearchWorkerEngine { - private contentPattern: RegExp; - private fileEncoding: string; private nextSearch = TPromise.wrap(null); - private isCanceled = false; - constructor(config: ISearchWorkerConfig) { - this.contentPattern = strings.createRegExp(config.pattern.pattern, config.pattern.isRegExp, { matchCase: config.pattern.isCaseSensitive, wholeWord: config.pattern.isWordMatch, multiline: false, global: true }); - this.fileEncoding = encodingExists(config.fileEncoding) ? config.fileEncoding : UTF8; - } - /** * Searches some number of the given paths concurrently, and starts searches in other paths when those complete. */ searchBatch(args: ISearchWorkerSearchArgs): TPromise { + const contentPattern = strings.createRegExp(args.pattern.pattern, args.pattern.isRegExp, { matchCase: args.pattern.isCaseSensitive, wholeWord: args.pattern.isWordMatch, multiline: false, global: true }); + const fileEncoding = encodingExists(args.fileEncoding) ? args.fileEncoding : UTF8; return this.nextSearch = - this.nextSearch.then(() => this._searchBatch(args)); + this.nextSearch.then(() => this._searchBatch(args, contentPattern, fileEncoding)); } - private _searchBatch(args: ISearchWorkerSearchArgs): TPromise { + private _searchBatch(args: ISearchWorkerSearchArgs, contentPattern: RegExp, fileEncoding: string): TPromise { if (this.isCanceled) { return TPromise.wrap(null); } @@ -97,7 +95,7 @@ export class SearchWorkerEngine { // Search in the given path, and when it's finished, search in the next path in absolutePaths const startSearchInFile = (absolutePath: string): TPromise => { - return this.searchInFile(absolutePath, this.contentPattern, this.fileEncoding, args.maxResults && (args.maxResults - result.numMatches)).then(fileResult => { + return this.searchInFile(absolutePath, contentPattern, fileEncoding, args.maxResults && (args.maxResults - result.numMatches)).then(fileResult => { // Finish early if search is canceled if (this.isCanceled) { return; diff --git a/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts b/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts index 6347aecc73c..72c70babb15 100644 --- a/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts +++ b/src/vs/workbench/services/search/node/worker/searchWorkerIpc.ts @@ -11,12 +11,9 @@ import { ISerializedFileMatch } from '../search'; import { IPatternInfo } from 'vs/platform/search/common/search'; import { SearchWorkerManager } from './searchWorker'; -export interface ISearchWorkerConfig { +export interface ISearchWorkerSearchArgs { pattern: IPatternInfo; fileEncoding: string; -} - -export interface ISearchWorkerSearchArgs { absolutePaths: string[]; maxResults?: number; } @@ -28,13 +25,13 @@ export interface ISearchWorkerSearchResult { } export interface ISearchWorker { - initialize(config: ISearchWorkerConfig): TPromise; + initialize(): TPromise; search(args: ISearchWorkerSearchArgs): TPromise; cancel(): TPromise; } export interface ISearchWorkerChannel extends IChannel { - call(command: 'initialize', config: ISearchWorkerConfig): TPromise; + call(command: 'initialize'): TPromise; call(command: 'search', args: ISearchWorkerSearchArgs): TPromise; call(command: 'cancel'): TPromise; call(command: string, arg?: any): TPromise; @@ -46,7 +43,7 @@ export class SearchWorkerChannel implements ISearchWorkerChannel { call(command: string, arg?: any): TPromise { switch (command) { - case 'initialize': return this.worker.initialize(arg); + case 'initialize': return this.worker.initialize(); case 'search': return this.worker.search(arg); case 'cancel': return this.worker.cancel(); } @@ -56,8 +53,8 @@ export class SearchWorkerChannel implements ISearchWorkerChannel { export class SearchWorkerChannelClient implements ISearchWorker { constructor(private channel: ISearchWorkerChannel) { } - initialize(config: ISearchWorkerConfig): TPromise { - return this.channel.call('initialize', config); + initialize(): TPromise { + return this.channel.call('initialize'); } search(args: ISearchWorkerSearchArgs): TPromise {