Skip to content

Commit

Permalink
Add unstable_perfLogger config option
Browse files Browse the repository at this point in the history
Summary: Extracts and simplifies the configurable `PerfLogger` from `metro-file-map` and lifts it into the base Metro config, so that we can add points and annotations elsewhere within Metro.

Reviewed By: motiz88

Differential Revision: D36875825

fbshipit-source-id: 51f7af6a6a7fb598fac94990143ac5fd0a3c8a68
  • Loading branch information
robhogan authored and facebook-github-bot committed Jun 9, 2022
1 parent e741990 commit eec0d7b
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 52 deletions.
18 changes: 18 additions & 0 deletions packages/metro-config/src/configTypes.flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,23 @@ export type Middleware = (
((e: ?Error) => mixed),
) => mixed;

type PerfAnnotations = $Shape<{
string: {[key: string]: string},
int: {[key: string]: number},
double: {[key: string]: number},
bool: {[key: string]: boolean},
string_array: {[key: string]: Array<string>},
int_array: {[key: string]: Array<number>},
double_array: {[key: string]: Array<number>},
bool_array: {[key: string]: Array<boolean>},
}>;

export interface PerfLogger {
point(name: string): void;
annotate(annotations: PerfAnnotations): void;
subSpan(label: string): PerfLogger;
}

type ResolverConfigT = {
assetExts: $ReadOnlyArray<string>,
assetResolutions: $ReadOnlyArray<string>,
Expand Down Expand Up @@ -121,6 +138,7 @@ type MetalConfigT = {
hasteMapCacheDirectory?: string, // Deprecated, alias of fileMapCacheDirectory
unstable_fileMapCacheManagerFactory?: CacheManagerFactory,
maxWorkers: number,
unstable_perfLogger?: ?PerfLogger,
projectRoot: string,
stickyWorkers: boolean,
transformerPath: string,
Expand Down
2 changes: 2 additions & 0 deletions packages/metro-config/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

'use strict';

export type * from './configTypes.flow';

const getDefaultConfig = require('./defaults');
const {loadConfig, mergeConfig, resolveConfig} = require('./loadConfig');

Expand Down
4 changes: 2 additions & 2 deletions packages/metro-file-map/src/crawlers/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ module.exports = async function nodeCrawl(options: CrawlerOptions): Promise<{
perfLogger,
roots,
} = options;
perfLogger?.markerPoint('nodeCrawl_start');
perfLogger?.point('nodeCrawl_start');
const useNativeFind = await hasNativeFindSupport(forceNodeFilesystemAPI);

return new Promise(resolve => {
Expand All @@ -239,7 +239,7 @@ module.exports = async function nodeCrawl(options: CrawlerOptions): Promise<{
});
data.files = files;

perfLogger?.markerPoint('nodeCrawl_end');
perfLogger?.point('nodeCrawl_end');
resolve({
hasteMap: data,
removedFiles,
Expand Down
34 changes: 17 additions & 17 deletions packages/metro-file-map/src/crawlers/watchman.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ module.exports = async function watchmanCrawl(
const {data, extensions, ignore, rootDir, roots, perfLogger} = options;
const clocks = data.clocks;

perfLogger?.markerPoint('watchmanCrawl_start');
perfLogger?.point('watchmanCrawl_start');
const client = new watchman.Client();

perfLogger?.markerPoint('watchmanCrawl/negotiateCapabilities_start');
perfLogger?.point('watchmanCrawl/negotiateCapabilities_start');
// https://facebook.github.io/watchman/docs/capabilities.html
// Check adds about ~28ms
const capabilities = await capabilityCheck(client, {
Expand Down Expand Up @@ -172,21 +172,21 @@ module.exports = async function watchmanCrawl(
}
}

perfLogger?.markerPoint('watchmanCrawl/negotiateCapabilities_end');
perfLogger?.point('watchmanCrawl/negotiateCapabilities_end');

async function getWatchmanRoots(
roots: $ReadOnlyArray<Path>,
): Promise<WatchmanRoots> {
perfLogger?.markerPoint('watchmanCrawl/getWatchmanRoots_start');
perfLogger?.point('watchmanCrawl/getWatchmanRoots_start');
const watchmanRoots = new Map();
await Promise.all(
roots.map(async (root, index) => {
perfLogger?.markerPoint(`watchmanCrawl/watchProject_${index}_start`);
perfLogger?.point(`watchmanCrawl/watchProject_${index}_start`);
const response = await cmd<WatchmanWatchProjectResponse>(
'watch-project',
root,
);
perfLogger?.markerPoint(`watchmanCrawl/watchProject_${index}_end`);
perfLogger?.point(`watchmanCrawl/watchProject_${index}_end`);
const existing = watchmanRoots.get(response.watch);
// A root can only be filtered if it was never seen with a
// relative_path before.
Expand All @@ -207,12 +207,12 @@ module.exports = async function watchmanCrawl(
}
}),
);
perfLogger?.markerPoint('watchmanCrawl/getWatchmanRoots_end');
perfLogger?.point('watchmanCrawl/getWatchmanRoots_end');
return watchmanRoots;
}

async function queryWatchmanForDirs(rootProjectDirMappings: WatchmanRoots) {
perfLogger?.markerPoint('watchmanCrawl/queryWatchmanForDirs_start');
perfLogger?.point('watchmanCrawl/queryWatchmanForDirs_start');
const results = new Map<string, WatchmanQueryResponse>();
let isFresh = false;
await Promise.all(
Expand All @@ -228,7 +228,7 @@ module.exports = async function watchmanCrawl(
// system and import it, transforming the clock into a local clock.
const since = clocks.get(fastPath.relative(rootDir, root));

perfLogger?.markerAnnotate({
perfLogger?.annotate({
bool: {
[`watchmanCrawl/query_${index}_has_clock`]: since != null,
},
Expand Down Expand Up @@ -294,19 +294,19 @@ module.exports = async function watchmanCrawl(
queryGenerator = 'suffix';
}

perfLogger?.markerAnnotate({
perfLogger?.annotate({
string: {
[`watchmanCrawl/query_${index}_generator`]: queryGenerator,
},
});

perfLogger?.markerPoint(`watchmanCrawl/query_${index}_start`);
perfLogger?.point(`watchmanCrawl/query_${index}_start`);
const response = await cmd<WatchmanQueryResponse>(
'query',
root,
query,
);
perfLogger?.markerPoint(`watchmanCrawl/query_${index}_end`);
perfLogger?.point(`watchmanCrawl/query_${index}_end`);

if ('warning' in response) {
console.warn('watchman warning: ', response.warning);
Expand All @@ -326,7 +326,7 @@ module.exports = async function watchmanCrawl(
),
);

perfLogger?.markerPoint('watchmanCrawl/queryWatchmanForDirs_end');
perfLogger?.point('watchmanCrawl/queryWatchmanForDirs_end');

return {
isFresh,
Expand Down Expand Up @@ -357,11 +357,11 @@ module.exports = async function watchmanCrawl(
}

if (clientError) {
perfLogger?.markerPoint('watchmanCrawl_end');
perfLogger?.point('watchmanCrawl_end');
throw clientError;
}

perfLogger?.markerPoint('watchmanCrawl/processResults_start');
perfLogger?.point('watchmanCrawl/processResults_start');

for (const [watchRoot, response] of results) {
const fsRoot = normalizePathSep(watchRoot);
Expand Down Expand Up @@ -438,8 +438,8 @@ module.exports = async function watchmanCrawl(

data.files = files;

perfLogger?.markerPoint('watchmanCrawl/processResults_end');
perfLogger?.markerPoint('watchmanCrawl_end');
perfLogger?.point('watchmanCrawl/processResults_end');
perfLogger?.point('watchmanCrawl_end');
if (didLogWatchmanWaitMessage) {
console.warn('Watchman query finished.');
}
Expand Down
19 changes: 3 additions & 16 deletions packages/metro-file-map/src/flow-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import type HasteFS from './HasteFS';
import type ModuleMap from './ModuleMap';
import type {Stats} from 'graceful-fs';
import type {PerfLogger} from 'metro-config';

export type {PerfLogger};

// These inputs affect the internal data collected for a given filesystem
// state, and changes may invalidate a cache.
Expand Down Expand Up @@ -160,22 +163,6 @@ export type ModuleMetaData = [/* path */ string, /* type */ number];

export type Path = string;

export interface PerfLogger {
markerPoint(name: string): void;
markerAnnotate(annotations: PerfAnnotations): void;
}

export type PerfAnnotations = $Shape<{
string: {[key: string]: string},
int: {[key: string]: number},
double: {[key: string]: number},
bool: {[key: string]: boolean},
string_array: {[key: string]: Array<string>},
int_array: {[key: string]: Array<number>},
double_array: {[key: string]: Array<number>},
bool_array: {[key: string]: Array<boolean>},
}>;

export type RawModuleMap = {
rootDir: Path,
duplicates: DuplicatesIndex,
Expand Down
34 changes: 17 additions & 17 deletions packages/metro-file-map/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ export default class HasteMap extends EventEmitter {

constructor(options: InputOptions) {
if (options.perfLogger) {
options.perfLogger?.markerPoint('constructor_start');
options.perfLogger?.point('constructor_start');
}
super();

Expand Down Expand Up @@ -327,7 +327,7 @@ export default class HasteMap extends EventEmitter {
this._buildPromise = null;
this._watchers = [];
this._worker = null;
this._options.perfLogger?.markerPoint('constructor_end');
this._options.perfLogger?.point('constructor_end');
}

static getCacheFilePath(
Expand Down Expand Up @@ -357,7 +357,7 @@ export default class HasteMap extends EventEmitter {
}

build(): Promise<InternalDataObject> {
this._options.perfLogger?.markerPoint('build_start');
this._options.perfLogger?.point('build_start');
if (!this._buildPromise) {
this._buildPromise = (async () => {
const data = await this._buildFileMap();
Expand Down Expand Up @@ -395,7 +395,7 @@ export default class HasteMap extends EventEmitter {
})();
}
return this._buildPromise.then(result => {
this._options.perfLogger?.markerPoint('build_end');
this._options.perfLogger?.point('build_end');
return result;
});
}
Expand All @@ -406,12 +406,12 @@ export default class HasteMap extends EventEmitter {
async read(): Promise<InternalData> {
let data: ?InternalData;

this._options.perfLogger?.markerPoint('read_start');
this._options.perfLogger?.point('read_start');
try {
data = await this._cacheManager.read();
} catch {}
data = data ?? this._createEmptyMap();
this._options.perfLogger?.markerPoint('read_end');
this._options.perfLogger?.point('read_end');

return data;
}
Expand All @@ -435,7 +435,7 @@ export default class HasteMap extends EventEmitter {
hasteMap: InternalData,
}> {
let hasteMap: InternalData;
this._options.perfLogger?.markerPoint('buildFileMap_start');
this._options.perfLogger?.point('buildFileMap_start');
try {
hasteMap =
this._options.resetCache === true
Expand All @@ -445,7 +445,7 @@ export default class HasteMap extends EventEmitter {
hasteMap = this._createEmptyMap();
}
return this._crawl(hasteMap).then(result => {
this._options.perfLogger?.markerPoint('buildFileMap_end');
this._options.perfLogger?.point('buildFileMap_end');
return result;
});
}
Expand Down Expand Up @@ -681,7 +681,7 @@ export default class HasteMap extends EventEmitter {
changedFiles?: FileData,
hasteMap: InternalData,
}): Promise<InternalData> {
this._options.perfLogger?.markerPoint('buildHasteMap_start');
this._options.perfLogger?.point('buildHasteMap_start');
const {removedFiles, changedFiles, hasteMap} = data;

// If any files were removed or we did not track what files changed, process
Expand Down Expand Up @@ -727,7 +727,7 @@ export default class HasteMap extends EventEmitter {
this._cleanup();
hasteMap.map = map;
hasteMap.mocks = mocks;
this._options.perfLogger?.markerPoint('buildHasteMap_end');
this._options.perfLogger?.point('buildHasteMap_end');
return hasteMap;
},
error => {
Expand All @@ -752,10 +752,10 @@ export default class HasteMap extends EventEmitter {
* 4. serialize the new `HasteMap` in a cache file.
*/
async _persist(hasteMap: InternalData) {
this._options.perfLogger?.markerPoint('persist_start');
this._options.perfLogger?.point('persist_start');
const snapshot = deepCloneInternalData(hasteMap);
await this._cacheManager.write(snapshot);
this._options.perfLogger?.markerPoint('persist_end');
this._options.perfLogger?.point('persist_end');
}

/**
Expand All @@ -778,7 +778,7 @@ export default class HasteMap extends EventEmitter {
}

_crawl(hasteMap: InternalData) {
this._options.perfLogger?.markerPoint('crawl_start');
this._options.perfLogger?.point('crawl_start');
const options = this._options;
const ignore = filePath => this._ignore(filePath);
const crawl =
Expand Down Expand Up @@ -819,7 +819,7 @@ export default class HasteMap extends EventEmitter {
};

const logEnd = <T>(result: T): T => {
this._options.perfLogger?.markerPoint('crawl_end');
this._options.perfLogger?.point('crawl_end');
return result;
};

Expand All @@ -834,9 +834,9 @@ export default class HasteMap extends EventEmitter {
* Watch mode
*/
_watch(hasteMap: InternalData): Promise<void> {
this._options.perfLogger?.markerPoint('watch_start');
this._options.perfLogger?.point('watch_start');
if (!this._options.watch) {
this._options.perfLogger?.markerPoint('watch_end');
this._options.perfLogger?.point('watch_end');
return Promise.resolve();
}

Expand Down Expand Up @@ -1046,7 +1046,7 @@ export default class HasteMap extends EventEmitter {
return Promise.all(this._options.roots.map(createWatcher)).then(
watchers => {
this._watchers = watchers;
this._options.perfLogger?.markerPoint('watch_end');
this._options.perfLogger?.point('watch_end');
},
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ function createHasteMap(
config.fileMapCacheDirectory ?? config.hasteMapCacheDirectory,
cacheFilePrefix: options?.cacheFilePrefix,
})),
perfLogger: config.unstable_perfLogger?.subSpan('hasteMap') ?? null,
computeDependencies,
computeSha1: true,
dependencyExtractor: config.resolver.dependencyExtractor,
Expand Down

0 comments on commit eec0d7b

Please sign in to comment.