From 69c6d8c12b7c954294c06345a9e265302165def5 Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Thu, 22 Feb 2018 16:24:33 +0000 Subject: [PATCH] fix(watchman): Parallelize Watchman calls in crawler again This is a follow up to #5615 where it made all async watchman commands serialized when converting them from promises to `async` functions. Existing Watchman crawler tests should pass, maybe slightly faster. --- .../jest-haste-map/src/crawlers/watchman.js | 74 ++++++++++--------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/packages/jest-haste-map/src/crawlers/watchman.js b/packages/jest-haste-map/src/crawlers/watchman.js index 945f68edc9bc..834258603e0f 100644 --- a/packages/jest-haste-map/src/crawlers/watchman.js +++ b/packages/jest-haste-map/src/crawlers/watchman.js @@ -51,48 +51,52 @@ module.exports = async function watchmanCrawl( try { const watchmanRoots = new Map(); - for (const root of roots) { - const response = await cmd('watch-project', root); - const existing = watchmanRoots.get(response.watch); - // A root can only be filtered if it was never seen with a relative_path before - const canBeFiltered = !existing || existing.length > 0; + await Promise.all( + roots.map(async root => { + const response = await cmd('watch-project', root); + const existing = watchmanRoots.get(response.watch); + // A root can only be filtered if it was never seen with a relative_path before + const canBeFiltered = !existing || existing.length > 0; - if (canBeFiltered) { - if (response.relative_path) { - watchmanRoots.set( - response.watch, - (existing || []).concat(response.relative_path), - ); - } else { - // Make the filter directories an empty array to signal that this root - // was already seen and needs to be watched for all files/directories - watchmanRoots.set(response.watch, []); + if (canBeFiltered) { + if (response.relative_path) { + watchmanRoots.set( + response.watch, + (existing || []).concat(response.relative_path), + ); + } else { + // Make the filter directories an empty array to signal that this root + // was already seen and needs to be watched for all files/directories + watchmanRoots.set(response.watch, []); + } } - } - } + }), + ); let shouldReset = false; const watchmanFileResults = new Map(); - for (const [root, directoryFilters] of watchmanRoots) { - const expression = Array.from(defaultWatchExpression); - if (directoryFilters.length > 0) { - expression.push([ - 'anyof', - ...directoryFilters.map(dir => ['dirname', dir]), - ]); - } - const fields = ['name', 'exists', 'mtime_ms']; + await Promise.all( + Array.from(watchmanRoots).map(async ([root, directoryFilters]) => { + const expression = Array.from(defaultWatchExpression); + if (directoryFilters.length > 0) { + expression.push([ + 'anyof', + ...directoryFilters.map(dir => ['dirname', dir]), + ]); + } + const fields = ['name', 'exists', 'mtime_ms']; - const query = clocks[root] - ? // Use the `since` generator if we have a clock available - {expression, fields, since: clocks[root]} - : // Otherwise use the `suffix` generator - {expression, fields, suffix: extensions}; + const query = clocks[root] + ? // Use the `since` generator if we have a clock available + {expression, fields, since: clocks[root]} + : // Otherwise use the `suffix` generator + {expression, fields, suffix: extensions}; - const response = await cmd('query', root, query); - shouldReset = shouldReset || response.is_fresh_instance; - watchmanFileResults.set(root, response); - } + const response = await cmd('query', root, query); + shouldReset = shouldReset || response.is_fresh_instance; + watchmanFileResults.set(root, response); + }), + ); // Reset the file map if watchman was restarted and sends us a list of files. if (shouldReset) {