Skip to content

Commit 38fb7c8

Browse files
robhoganmeta-codesync[bot]
authored andcommitted
File map crawl retries, prefer async/await (#1668)
Summary: Pull Request resolved: #1668 Modernise and cleanup this logic a little bit to reduce the noise of an upcoming change. Changelog: Internal Reviewed By: vzaidman Differential Revision: D96136859 fbshipit-source-id: ea02f2a529173ee31d0c6e7c56a56d828e8b0ed4
1 parent c9e9fe6 commit 38fb7c8

9 files changed

Lines changed: 73 additions & 96 deletions

File tree

packages/metro-file-map/src/Watcher.js

Lines changed: 37 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@
1111
import type {
1212
Console,
1313
CrawlerOptions,
14-
FileData,
14+
CrawlResult,
1515
Path,
1616
PerfLogger,
1717
WatcherBackend,
1818
WatcherBackendChangeEvent,
19-
WatchmanClocks,
2019
} from './flow-types';
2120
import type {WatcherOptions as WatcherBackendOptions} from './watchers/common';
2221

@@ -37,12 +36,6 @@ const debug = require('debug')('Metro:Watcher');
3736

3837
const MAX_WAIT_TIME = 240000;
3938

40-
type CrawlResult = {
41-
changedFiles: FileData,
42-
clocks?: WatchmanClocks,
43-
removedFiles: Set<Path>,
44-
};
45-
4639
type WatcherOptions = {
4740
abortSignal: AbortSignal,
4841
computeSha1: boolean,
@@ -113,50 +106,45 @@ export class Watcher extends EventEmitter {
113106
roots: options.roots,
114107
};
115108

116-
const retry = (error: Error): Promise<CrawlResult> => {
117-
if (crawl === watchmanCrawl) {
118-
crawler = 'node';
119-
options.console.warn(
120-
'metro-file-map: Watchman crawl failed. Retrying once with node ' +
121-
'crawler.\n' +
122-
" Usually this happens when watchman isn't running. Create an " +
123-
"empty `.watchmanconfig` file in your project's root folder or " +
124-
'initialize a git or hg repository in your project.\n' +
125-
' ' +
126-
error.toString(),
127-
);
128-
// $FlowFixMe[incompatible-type] Found when updating Promise type definition
129-
return nodeCrawl(crawlerOptions).catch<CrawlResult>(e => {
130-
throw new Error(
131-
'Crawler retry failed:\n' +
132-
` Original error: ${error.message}\n` +
133-
` Retry error: ${e.message}\n`,
134-
);
135-
});
136-
}
137-
138-
throw error;
139-
};
140-
141-
const logEnd = (delta: CrawlResult): CrawlResult => {
142-
debug(
143-
'Crawler "%s" returned %d added/modified, %d removed, %d clock(s).',
144-
crawler,
145-
delta.changedFiles.size,
146-
delta.removedFiles.size,
147-
delta.clocks?.size ?? 0,
148-
);
149-
this.#options.perfLogger?.point('crawl_end');
150-
return delta;
151-
};
152-
153109
debug('Beginning crawl with "%s".', crawler);
110+
111+
let delta: CrawlResult;
154112
try {
155-
// $FlowFixMe[incompatible-type] Found when updating Promise type definition
156-
return crawl(crawlerOptions).catch<CrawlResult>(retry).then(logEnd);
157-
} catch (error) {
158-
return retry(error).then(logEnd);
113+
delta = await crawl(crawlerOptions);
114+
} catch (firstError) {
115+
if (crawl !== watchmanCrawl) {
116+
throw firstError;
117+
}
118+
crawler = 'node';
119+
options.console.warn(
120+
'metro-file-map: Watchman crawl failed. Retrying once with node ' +
121+
'crawler.\n' +
122+
" Usually this happens when watchman isn't running. Create an " +
123+
"empty `.watchmanconfig` file in your project's root folder or " +
124+
'initialize a git or hg repository in your project.\n' +
125+
' ' +
126+
firstError.toString(),
127+
);
128+
try {
129+
delta = await nodeCrawl(crawlerOptions);
130+
} catch (retryError) {
131+
throw new Error(
132+
'Crawler retry failed:\n' +
133+
` Original error: ${firstError.message}\n` +
134+
` Retry error: ${retryError.message}\n`,
135+
);
136+
}
159137
}
138+
139+
debug(
140+
'Crawler "%s" returned %d added/modified, %d removed, %d clock(s).',
141+
crawler,
142+
delta.changedFiles.size,
143+
delta.removedFiles.size,
144+
delta.clocks?.size ?? 0,
145+
);
146+
this.#options.perfLogger?.point('crawl_end');
147+
return delta;
160148
}
161149

162150
async watch(onChange: (change: WatcherBackendChangeEvent) => void) {

packages/metro-file-map/src/crawlers/node/index.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
*/
1111

1212
import type {
13-
CanonicalPath,
1413
Console,
1514
CrawlerOptions,
15+
CrawlResult,
1616
FileData,
1717
IgnoreMatcher,
1818
} from '../../flow-types';
@@ -170,10 +170,9 @@ function findNative(
170170
});
171171
}
172172

173-
export default async function nodeCrawl(options: CrawlerOptions): Promise<{
174-
removedFiles: Set<CanonicalPath>,
175-
changedFiles: FileData,
176-
}> {
173+
export default async function nodeCrawl(
174+
options: CrawlerOptions,
175+
): Promise<CrawlResult> {
177176
const {
178177
console,
179178
previousState,

packages/metro-file-map/src/crawlers/watchman/index.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ import type {WatchmanClockSpec} from '../../flow-types';
1313
import type {
1414
CanonicalPath,
1515
CrawlerOptions,
16+
CrawlResult,
1617
FileData,
1718
FileMetadata,
1819
Path,
19-
WatchmanClocks,
2020
} from '../../flow-types';
2121
import type {WatchmanQueryResponse, WatchmanWatchResponse} from 'fb-watchman';
2222

@@ -57,11 +57,7 @@ export default async function watchmanCrawl({
5757
previousState,
5858
rootDir,
5959
roots,
60-
}: CrawlerOptions): Promise<{
61-
changedFiles: FileData,
62-
removedFiles: Set<CanonicalPath>,
63-
clocks: WatchmanClocks,
64-
}> {
60+
}: CrawlerOptions): Promise<CrawlResult> {
6561
abortSignal?.throwIfAborted();
6662

6763
const client = new watchman.Client();

packages/metro-file-map/src/flow-types.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,17 @@ export type CrawlerOptions = {
127127
onStatus: (status: WatcherStatus) => void,
128128
};
129129

130+
export type CrawlResult =
131+
| {
132+
changedFiles: FileData,
133+
removedFiles: Set<Path>,
134+
clocks: WatchmanClocks,
135+
}
136+
| {
137+
changedFiles: FileData,
138+
removedFiles: Set<Path>,
139+
};
140+
130141
export type DependencyExtractor = {
131142
extract: (
132143
content: string,

packages/metro-file-map/src/index.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import type {
2323
ChangeEventMetadata,
2424
Console,
2525
CrawlerOptions,
26+
CrawlResult,
2627
FileData,
2728
FileMapPlugin,
2829
FileMapPluginWorker,
@@ -506,11 +507,7 @@ export default class FileMap extends EventEmitter {
506507
*/
507508
async #buildFileDelta(
508509
previousState: CrawlerOptions['previousState'],
509-
): Promise<{
510-
removedFiles: Set<CanonicalPath>,
511-
changedFiles: FileData,
512-
clocks?: WatchmanClocks,
513-
}> {
510+
): Promise<CrawlResult> {
514511
this.#startupPerfLogger?.point('buildFileDelta_start');
515512

516513
const {
@@ -554,10 +551,9 @@ export default class FileMap extends EventEmitter {
554551

555552
watcher.on('status', status => this.emit('status', status));
556553

557-
return watcher.crawl().then(result => {
558-
this.#startupPerfLogger?.point('buildFileDelta_end');
559-
return result;
560-
});
554+
const result = await watcher.crawl();
555+
this.#startupPerfLogger?.point('buildFileDelta_end');
556+
return result;
561557
}
562558

563559
#maybeReadLink(normalPath: Path, fileMetadata: FileMetadata): ?Promise<void> {

packages/metro-file-map/types/Watcher.d.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* LICENSE file in the root directory of this source tree.
66
*
77
* @noformat
8-
* @generated SignedSource<<7537b04fdc97fb54ebddaebf60605405>>
8+
* @generated SignedSource<<296395484c53039955e7789570880079>>
99
*
1010
* This file was translated from Flow by scripts/generateTypeScriptDefinitions.js
1111
* Original file: packages/metro-file-map/src/Watcher.js
@@ -17,20 +17,13 @@
1717
import type {
1818
Console,
1919
CrawlerOptions,
20-
FileData,
21-
Path,
20+
CrawlResult,
2221
PerfLogger,
2322
WatcherBackendChangeEvent,
24-
WatchmanClocks,
2523
} from './flow-types';
2624

2725
import EventEmitter from 'events';
2826

29-
type CrawlResult = {
30-
changedFiles: FileData;
31-
clocks?: WatchmanClocks;
32-
removedFiles: Set<Path>;
33-
};
3427
type WatcherOptions = {
3528
abortSignal: AbortSignal;
3629
computeSha1: boolean;

packages/metro-file-map/types/crawlers/node/index.d.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* @noformat
88
* @oncall react_native
9-
* @generated SignedSource<<8851cd12d3cd8bdda798362696c830a2>>
9+
* @generated SignedSource<<27109494e4956802ba89ac6fd22aa277>>
1010
*
1111
* This file was translated from Flow by scripts/generateTypeScriptDefinitions.js
1212
* Original file: packages/metro-file-map/src/crawlers/node/index.js
@@ -15,9 +15,7 @@
1515
* yarn run build-ts-defs (OSS)
1616
*/
1717

18-
import type {CanonicalPath, CrawlerOptions, FileData} from '../../flow-types';
18+
import type {CrawlerOptions, CrawlResult} from '../../flow-types';
1919

20-
declare function nodeCrawl(
21-
options: CrawlerOptions,
22-
): Promise<{removedFiles: Set<CanonicalPath>; changedFiles: FileData}>;
20+
declare function nodeCrawl(options: CrawlerOptions): Promise<CrawlResult>;
2321
export default nodeCrawl;

packages/metro-file-map/types/crawlers/watchman/index.d.ts

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* @noformat
88
* @oncall react_native
9-
* @generated SignedSource<<94c8a03429d06b694e26ca524fb9f17c>>
9+
* @generated SignedSource<<bcfb58810773510450845bc00a93beae>>
1010
*
1111
* This file was translated from Flow by scripts/generateTypeScriptDefinitions.js
1212
* Original file: packages/metro-file-map/src/crawlers/watchman/index.js
@@ -15,16 +15,9 @@
1515
* yarn run build-ts-defs (OSS)
1616
*/
1717

18-
import type {
19-
CanonicalPath,
20-
CrawlerOptions,
21-
FileData,
22-
WatchmanClocks,
23-
} from '../../flow-types';
18+
import type {CrawlerOptions, CrawlResult} from '../../flow-types';
2419

25-
declare function watchmanCrawl($$PARAM_0$$: CrawlerOptions): Promise<{
26-
changedFiles: FileData;
27-
removedFiles: Set<CanonicalPath>;
28-
clocks: WatchmanClocks;
29-
}>;
20+
declare function watchmanCrawl(
21+
$$PARAM_0$$: CrawlerOptions,
22+
): Promise<CrawlResult>;
3023
export default watchmanCrawl;

packages/metro-file-map/types/flow-types.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* @noformat
88
* @oncall react_native
9-
* @generated SignedSource<<8c5030c48241b474468d59538c2e34e3>>
9+
* @generated SignedSource<<51ef2d9b353f0cec5e93976e27e3e2f8>>
1010
*
1111
* This file was translated from Flow by scripts/generateTypeScriptDefinitions.js
1212
* Original file: packages/metro-file-map/src/flow-types.js
@@ -107,6 +107,9 @@ export type CrawlerOptions = {
107107
roots: ReadonlyArray<string>;
108108
onStatus: (status: WatcherStatus) => void;
109109
};
110+
export type CrawlResult =
111+
| {changedFiles: FileData; removedFiles: Set<Path>; clocks: WatchmanClocks}
112+
| {changedFiles: FileData; removedFiles: Set<Path>};
110113
export type DependencyExtractor = {
111114
extract: (
112115
content: string,

0 commit comments

Comments
 (0)