Skip to content

Commit

Permalink
Reduce exceptions (microsoft#44710)
Browse files Browse the repository at this point in the history
* Don't visit non-existent basePaths

* Stop trying to add file watchers after hitting the system limit

* Update tests
  • Loading branch information
amcasey authored Jun 28, 2021
1 parent 066796b commit c0d5c29
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 7 deletions.
12 changes: 10 additions & 2 deletions src/compiler/sys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,7 @@ namespace ts {
let activeSession: import("inspector").Session | "stopping" | undefined;
let profilePath = "./profile.cpuprofile";

let hitSystemWatcherLimit = false;

const Buffer: {
new (input: string, encoding?: string): any;
Expand Down Expand Up @@ -1619,6 +1620,12 @@ namespace ts {
options = { persistent: true };
}
}

if (hitSystemWatcherLimit) {
sysLog(`sysLog:: ${fileOrDirectory}:: Defaulting to fsWatchFile`);
return watchPresentFileSystemEntryWithFsWatchFile();
}

try {
const presentWatcher = _fs.watch(
fileOrDirectory,
Expand All @@ -1635,6 +1642,8 @@ namespace ts {
// Catch the exception and use polling instead
// Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
// so instead of throwing error, use fs.watchFile
hitSystemWatcherLimit ||= e.code === "ENOSPC";
sysLog(`sysLog:: ${fileOrDirectory}:: Changing to fsWatchFile`);
return watchPresentFileSystemEntryWithFsWatchFile();
}
}
Expand All @@ -1656,7 +1665,6 @@ namespace ts {
* Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
*/
function watchPresentFileSystemEntryWithFsWatchFile(): FileWatcher {
sysLog(`sysLog:: ${fileOrDirectory}:: Changing to fsWatchFile`);
return watchFile(
fileOrDirectory,
createFileWatcherCallback(callback),
Expand Down Expand Up @@ -1796,7 +1804,7 @@ namespace ts {
}

function readDirectory(path: string, extensions?: readonly string[], excludes?: readonly string[], includes?: readonly string[], depth?: number): string[] {
return matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
return matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath, directoryExists);
}

function fileSystemEntryExists(path: string, entryKind: FileSystemEntryKind): boolean {
Expand Down
6 changes: 4 additions & 2 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6515,7 +6515,7 @@ namespace ts {
}

/** @param path directory of the tsconfig.json */
export function matchFiles(path: string, extensions: readonly string[] | undefined, excludes: readonly string[] | undefined, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => FileSystemEntries, realpath: (path: string) => string): string[] {
export function matchFiles(path: string, extensions: readonly string[] | undefined, excludes: readonly string[] | undefined, includes: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => FileSystemEntries, realpath: (path: string) => string, directoryExists: (path: string) => boolean): string[] {
path = normalizePath(path);
currentDirectory = normalizePath(currentDirectory);

Expand All @@ -6531,7 +6531,9 @@ namespace ts {
const visited = new Map<string, true>();
const toCanonical = createGetCanonicalFileName(useCaseSensitiveFileNames);
for (const basePath of patterns.basePaths) {
visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth);
if (directoryExists(basePath)) {
visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth);
}
}

return flatten(results);
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/watchUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ namespace ts {
const rootResult = tryReadDirectory(rootDir, rootDirPath);
let rootSymLinkResult: FileSystemEntries | undefined;
if (rootResult !== undefined) {
return matchFiles(rootDir, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries, realpath);
return matchFiles(rootDir, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries, realpath, directoryExists);
}
return host.readDirectory!(rootDir, extensions, excludes, includes, depth);

Expand Down
2 changes: 1 addition & 1 deletion src/harness/fakesHosts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ namespace fakes {
}

public readDirectory(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): string[] {
return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, path => this.getAccessibleFileSystemEntries(path), path => this.realpath(path));
return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, path => this.getAccessibleFileSystemEntries(path), path => this.realpath(path), path => this.directoryExists(path));
}

public getAccessibleFileSystemEntries(path: string): ts.FileSystemEntries {
Expand Down
2 changes: 1 addition & 1 deletion src/harness/virtualFileSystemWithWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,7 @@ interface Array<T> { length: number; [n: number]: T; }`
});
}
return { directories, files };
}, path => this.realpath(path));
}, path => this.realpath(path), path => this.directoryExists(path));
}

createHash(s: string): string {
Expand Down

0 comments on commit c0d5c29

Please sign in to comment.