From 320874989f7fc18b963ebfc2c955aeb623ec5acc Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 18 Oct 2016 13:33:24 -0400 Subject: [PATCH] Implement and use optimisticReadJsonOrNull for better caching. The problem with optimisticReadFile is that it doesn't cache anything when the file is missing, because files.readFile throws an ENOENT exception. --- tools/fs/optimistic.js | 17 +++++++++++++++-- tools/isobuild/meteor-npm.js | 26 +++++++------------------- tools/isobuild/resolver.js | 21 ++------------------- 3 files changed, 24 insertions(+), 40 deletions(-) diff --git a/tools/fs/optimistic.js b/tools/fs/optimistic.js index f49c2593af..4c16a4c03a 100644 --- a/tools/fs/optimistic.js +++ b/tools/fs/optimistic.js @@ -122,9 +122,9 @@ export const optimisticStatOrNull = makeOptimistic("statOrNull", statOrNull); export const optimisticLStat = makeOptimistic("lstat", lstat); export const optimisticReadFile = makeOptimistic("readFile", readFile); export const optimisticReaddir = makeOptimistic("readdir", readdir); -export const optimisticHashOrNull = makeOptimistic("hashOrNull", path => { +export const optimisticHashOrNull = makeOptimistic("hashOrNull", (...args) => { try { - return sha1(optimisticReadFile(path)); + return sha1(optimisticReadFile(...args)); } catch (e) { if (e.code !== "EISDIR" && @@ -135,3 +135,16 @@ export const optimisticHashOrNull = makeOptimistic("hashOrNull", path => { return null; }); + +export const optimisticReadJsonOrNull = +makeOptimistic("readJsonOrNull", (...args) => { + try { + return JSON.parse(optimisticReadFile(...args)); + } catch (e) { + if (! (e instanceof SyntaxError || + e.code === "ENOENT")) { + throw e; + } + } + return null; +}); diff --git a/tools/isobuild/meteor-npm.js b/tools/isobuild/meteor-npm.js index ebce33d66f..2e97d6217b 100644 --- a/tools/isobuild/meteor-npm.js +++ b/tools/isobuild/meteor-npm.js @@ -27,7 +27,7 @@ import { dirtyNpmPackageByName, optimisticLStat, optimisticStatOrNull, - optimisticReadFile, + optimisticReadJsonOrNull, optimisticReaddir, } from "../fs/optimistic.js"; @@ -146,7 +146,7 @@ export function getProdPackageNames(nodeModulesDir) { if (packageJsonStat && packageJsonStat.isFile()) { - const pkg = JSON.parse(optimisticReadFile(packageJsonPath)); + const pkg = optimisticReadJsonOrNull(packageJsonPath); const nodeModulesDir = files.pathJoin(dir, "node_modules"); nodeModulesDirStack.push(nodeModulesDir); @@ -268,16 +268,8 @@ function rebuildVersionsAreCompatible(pkgPath) { const versionFile = files.pathJoin(pkgPath, lastRebuildJSONFilename); - try { - var versions = JSON.parse(files.readFile(versionFile)); - } catch (e) { - if (! (e instanceof SyntaxError || - e.code === "ENOENT")) { - throw e; - } - } - - return versionsAreCompatible(versions); + return versionsAreCompatible( + optimisticReadJsonOrNull(versionFile)); } // Rebuilds any binary dependencies in the given node_modules directory, @@ -458,13 +450,9 @@ const isPortable = Profile("meteorNpm.isPortable", dir => { // put .meteor-portable files only in the individual top-level package // directories, so that they will get cleared away the next time those // packages are (re)installed. - try { - return JSON.parse(optimisticReadFile(portableFile)); - } catch (e) { - if (! (e instanceof SyntaxError || - e.code === "ENOENT")) { - throw e; - } + const result = optimisticReadJsonOrNull(portableFile); + if (result) { + return result; } } else { // Clean up any .meteor-portable files we mistakenly wrote in diff --git a/tools/isobuild/resolver.js b/tools/isobuild/resolver.js index a5f48a79ff..bf8d0f4176 100644 --- a/tools/isobuild/resolver.js +++ b/tools/isobuild/resolver.js @@ -21,7 +21,7 @@ import LRU from "lru-cache"; import { wrap } from "optimism"; import { optimisticStatOrNull, - optimisticReadFile, + optimisticReadJsonOrNull, } from "../fs/optimistic.js"; const nativeModulesMap = Object.create(null); @@ -279,26 +279,9 @@ export default class Resolver { return resolved || "missing"; } - _readPkgJson(path) { - if (! optimisticStatOrNull(path)) { - return null; - } - - try { - return JSON.parse(optimisticReadFile(path)); - } catch (e) { - if (! (e instanceof SyntaxError || - e.code === "ENOENT")) { - throw e; - } - } - - return null; - } - _resolvePkgJsonMain(dirPath, _seenDirPaths) { const pkgJsonPath = pathJoin(dirPath, "package.json"); - const pkg = this._readPkgJson(pkgJsonPath); + const pkg = optimisticReadJsonOrNull(pkgJsonPath); if (! pkg) { return null; }