Use different cache keys for Package objects (fixes #2949)

Summary: @​public

Dead-lock trying to read package.json because it's both a "module" and a "package". in `Module.getName` it uses the cache key "name" and tries to call `Package.getName` which uses the same cache key and we end up returning the same promise that we're trying to resolve resulting in a dead-lock.

This changes the cache keys for the packages that adds a prefix "package-".

Reviewed By: @vjeux

Differential Revision: D2506979
This commit is contained in:
Amjad Masad 2015-10-04 12:31:07 -07:00 committed by facebook-github-bot-5
parent 3cdd8d0320
commit 8356b609a5
2 changed files with 134 additions and 2 deletions

View File

@ -227,6 +227,55 @@ describe('DependencyGraph', function() {
}); });
}); });
pit('should get package json as a dep', () => {
var root = '/root';
fs.__setMockFilesystem({
'root': {
'package.json': JSON.stringify({
name: 'package'
}),
'index.js': [
'/**',
' * @providesModule index',
' */',
'require("./package.json")',
].join('\n'),
}
});
var dgraph = new DependencyGraph({
roots: [root],
fileWatcher: fileWatcher,
assetExts: ['png', 'jpg'],
cache: cache,
});
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(deps => {
expect(deps)
.toEqual([
{
id: 'index',
path: '/root/index.js',
dependencies: ['./package.json'],
isAsset: false,
isAsset_DEPRECATED: false,
isJSON: false,
isPolyfill: false,
resolution: undefined,
},
{
id: 'package/package.json',
isJSON: true,
path: '/root/package.json',
dependencies: [],
isAsset: false,
isAsset_DEPRECATED: false,
isPolyfill: false,
resolution: undefined,
},
]);
});
});
pit('should get dependencies with deprecated assets', function() { pit('should get dependencies with deprecated assets', function() {
var root = '/root'; var root = '/root';
fs.__setMockFilesystem({ fs.__setMockFilesystem({
@ -2619,6 +2668,89 @@ describe('DependencyGraph', function() {
]); ]);
}); });
}); });
pit('should require package.json', () => {
var root = '/root';
fs.__setMockFilesystem({
'root': {
'index.js': [
'/**',
' * @providesModule index',
' */',
'require("foo/package.json");',
'require("bar");',
].join('\n'),
'node_modules': {
'foo': {
'package.json': JSON.stringify({
name: 'foo',
main: 'main.js',
}),
},
'bar': {
'package.json': JSON.stringify({
name: 'bar',
main: 'main.js',
}),
'main.js': 'require("./package.json")',
},
},
}
});
var dgraph = new DependencyGraph({
roots: [root],
fileWatcher: fileWatcher,
assetExts: ['png', 'jpg'],
cache: cache,
});
return getOrderedDependenciesAsJSON(dgraph, '/root/index.js').then(deps => {
expect(deps)
.toEqual([
{
id: 'index',
path: '/root/index.js',
dependencies: ['foo/package.json', 'bar'],
isAsset: false,
isAsset_DEPRECATED: false,
isJSON: false,
isPolyfill: false,
resolution: undefined,
},
{
id: 'foo/package.json',
path: '/root/node_modules/foo/package.json',
dependencies: [],
isAsset: false,
isAsset_DEPRECATED: false,
isJSON: true,
isPolyfill: false,
resolution: undefined,
},
{
id: 'bar/main.js',
path: '/root/node_modules/bar/main.js',
dependencies: ['./package.json'],
isAsset: false,
isAsset_DEPRECATED: false,
isJSON: false,
isPolyfill: false,
resolution: undefined,
},
{
id: 'bar/package.json',
path: '/root/node_modules/bar/package.json',
dependencies: [],
isAsset: false,
isAsset_DEPRECATED: false,
isJSON: true,
isPolyfill: false,
resolution: undefined,
},
]);
});
});
}); });
describe('file watch updating', function() { describe('file watch updating', function() {

View File

@ -34,13 +34,13 @@ class Package {
} }
isHaste() { isHaste() {
return this._cache.get(this.path, 'haste', () => return this._cache.get(this.path, 'package-haste', () =>
this._read().then(json => !!json.name) this._read().then(json => !!json.name)
); );
} }
getName() { getName() {
return this._cache.get(this.path, 'name', () => return this._cache.get(this.path, 'package-name', () =>
this._read().then(json => json.name) this._read().then(json => json.name)
); );
} }