[Pkg-javascript-commits] [node-module-deps] 361/444: Fix input rows race condition
Bastien Roucariès
rouca at moszumanska.debian.org
Fri Dec 15 09:48:13 UTC 2017
This is an automated email from the git hooks/post-receive script.
rouca pushed a commit to branch master
in repository node-module-deps.
commit 9080ba995043708a35601dc49d2a719e77d08929
Author: Andres Suarez <zertosh at gmail.com>
Date: Sat Apr 18 23:39:22 2015 -0400
Fix input rows race condition
---
index.js | 34 +++++++++-----
test/cache.js | 50 +++++++++++++++++++++
test/cache_expose.js | 54 ++++++++++++++++++++++
test/cache_partial.js | 47 +++++++++++++++++++
test/cache_partial_expose.js | 104 +++++++++++++++++++++++++++++++++++++++++++
test/expose/bar.js | 1 +
test/expose/foo.js | 1 +
test/expose/lib/abc.js | 1 +
test/expose/lib/xyz.js | 2 +
test/expose/main.js | 3 ++
10 files changed, 286 insertions(+), 11 deletions(-)
diff --git a/index.js b/index.js
index 01e8b33..307924e 100644
--- a/index.js
+++ b/index.js
@@ -58,6 +58,7 @@ function Deps (opts) {
// modules in it. If not, set it anyway so it's defined later.
if (!this.options.expose) this.options.expose = {};
this.pending = 0;
+ this.inputPending = 0;
var topfile = path.join(this.basedir, '__fake.js');
this.top = {
@@ -298,10 +299,13 @@ Deps.prototype.walk = function (id, parent, cb) {
this.pending ++;
var rec = {};
+ var input;
if (typeof id === 'object') {
rec = copy(id);
if (rec.entry === false) delete rec.entry;
id = rec.file || rec.id;
+ input = true;
+ this.inputPending ++;
}
self.resolve(id, parent, function (err, file, pkg) {
@@ -319,6 +323,7 @@ Deps.prototype.walk = function (id, parent, cb) {
if (opts.postFilter && !opts.postFilter(id, file, pkg)) {
if (--self.pending === 0) self.push(null);
+ if (input) --self.inputPending;
return cb(null, undefined);
}
if (err && rec.source) {
@@ -333,12 +338,14 @@ Deps.prototype.walk = function (id, parent, cb) {
}
if (err && self.options.ignoreMissing) {
if (--self.pending === 0) self.push(null);
+ if (input) --self.inputPending;
self.emit('missing', id, parent);
return cb && cb(null, undefined);
}
if (err) return self.emit('error', err);
if (self.visited[file]) {
if (-- self.pending === 0) self.push(null);
+ if (input) --self.inputPending;
return cb && cb(null, file);
}
self.visited[file] = true;
@@ -380,18 +387,23 @@ Deps.prototype.walk = function (id, parent, cb) {
};
var resolved = {};
- deps.forEach(function (id) {
- if (opts.filter && !opts.filter(id)) {
- resolved[id] = false;
- if (--p === 0) done();
- return;
- }
- self.walk(id, current, function (err, r) {
- resolved[id] = r;
- if (--p === 0) done();
+ if (input) --self.inputPending;
+
+ (function resolve () {
+ if (self.inputPending > 0) return setTimeout(resolve);
+ deps.forEach(function (id) {
+ if (opts.filter && !opts.filter(id)) {
+ resolved[id] = false;
+ if (--p === 0) done();
+ return;
+ }
+ self.walk(id, current, function (err, r) {
+ resolved[id] = r;
+ if (--p === 0) done();
+ });
});
- });
- if (deps.length === 0) done();
+ if (deps.length === 0) done();
+ })();
function done () {
if (!rec.id) rec.id = file;
diff --git a/test/cache.js b/test/cache.js
new file mode 100644
index 0000000..a1fdd59
--- /dev/null
+++ b/test/cache.js
@@ -0,0 +1,50 @@
+var parser = require('../');
+var test = require('tape');
+var path = require('path');
+
+var files = {
+ foo: path.join(__dirname, '/files/foo.js'),
+ bar: path.join(__dirname, '/files/bar.js')
+};
+
+var sources = {
+ foo: 'notreal foo',
+ bar: 'notreal bar'
+};
+
+var cache = {};
+cache[files.foo] = {
+ source: sources.foo,
+ deps: { './bar': files.bar }
+};
+cache[files.bar] = {
+ source: sources.bar,
+ deps: {}
+};
+
+test('uses cache', function (t) {
+ t.plan(1);
+ var p = parser({ cache: cache });
+ p.end({ id: 'foo', file: files.foo, entry: false });
+
+ var rows = [];
+ p.on('data', function (row) { rows.push(row) });
+ p.on('end', function () {
+ t.same(rows.sort(cmp), [
+ {
+ id: 'foo',
+ file: files.foo,
+ source: sources.foo,
+ deps: { './bar': files.bar }
+ },
+ {
+ id: files.bar,
+ file: files.bar,
+ source: sources.bar,
+ deps: {}
+ }
+ ].sort(cmp));
+ });
+});
+
+function cmp (a, b) { return a.id < b.id ? -1 : 1 }
diff --git a/test/cache_expose.js b/test/cache_expose.js
new file mode 100644
index 0000000..d1e3fe3
--- /dev/null
+++ b/test/cache_expose.js
@@ -0,0 +1,54 @@
+var parser = require('../');
+var test = require('tape');
+var path = require('path');
+
+var files = {
+ foo: path.join(__dirname, '/files/foo.js'),
+ bar: path.join(__dirname, '/files/bar.js')
+};
+
+var sources = {
+ foo: 'notreal foo',
+ bar: 'notreal bar'
+};
+
+var cache = {};
+cache[files.foo] = {
+ source: sources.foo,
+ deps: { './bar': files.bar }
+};
+cache[files.bar] = {
+ source: sources.bar,
+ deps: {}
+};
+
+test('cache preserves expose and entry', function (t) {
+ t.plan(1);
+ var p = parser({ cache: cache });
+ p.write({ id: files.bar, expose: 'bar2', entry: false });
+ p.end({ id: 'foo', file: files.foo, entry: true, expose: 'foo2' });
+
+ var rows = [];
+ p.on('data', function (row) { rows.push(row) });
+ p.on('end', function () {
+ t.same(rows.sort(cmp), [
+ {
+ id: 'foo',
+ expose: 'foo2',
+ entry: true,
+ file: files.foo,
+ source: sources.foo,
+ deps: { './bar': files.bar }
+ },
+ {
+ id: files.bar,
+ expose: 'bar2',
+ file: files.bar,
+ source: sources.bar,
+ deps: {}
+ }
+ ].sort(cmp));
+ });
+});
+
+function cmp (a, b) { return a.id < b.id ? -1 : 1 }
diff --git a/test/cache_partial.js b/test/cache_partial.js
new file mode 100644
index 0000000..4299dea
--- /dev/null
+++ b/test/cache_partial.js
@@ -0,0 +1,47 @@
+var parser = require('../');
+var test = require('tape');
+var fs = require('fs');
+var path = require('path');
+
+var files = {
+ foo: path.join(__dirname, '/files/foo.js'),
+ bar: path.join(__dirname, '/files/bar.js')
+};
+
+var sources = {
+ foo: 'notreal foo',
+ bar: fs.readFileSync(files.bar, 'utf8')
+};
+
+var cache = {};
+cache[files.foo] = {
+ source: sources.foo,
+ deps: { './bar': files.bar }
+};
+
+test('uses cache and reads from disk', function (t) {
+ t.plan(1);
+ var p = parser({ cache: cache });
+ p.end({ id: 'foo', file: files.foo, entry: false });
+
+ var rows = [];
+ p.on('data', function (row) { rows.push(row) });
+ p.on('end', function () {
+ t.same(rows.sort(cmp), [
+ {
+ id: 'foo',
+ file: files.foo,
+ source: sources.foo,
+ deps: { './bar': files.bar }
+ },
+ {
+ id: files.bar,
+ file: files.bar,
+ source: sources.bar,
+ deps: {}
+ }
+ ].sort(cmp));
+ });
+});
+
+function cmp (a, b) { return a.id < b.id ? -1 : 1 }
diff --git a/test/cache_partial_expose.js b/test/cache_partial_expose.js
new file mode 100644
index 0000000..e851ab2
--- /dev/null
+++ b/test/cache_partial_expose.js
@@ -0,0 +1,104 @@
+var parser = require('../');
+var test = require('tape');
+var fs = require('fs');
+var path = require('path');
+var copy = require('shallow-copy');
+
+var files = {
+ abc: path.join(__dirname, '/expose/lib/abc.js'),
+ xyz: path.join(__dirname, '/expose/lib/xyz.js'),
+ foo: path.join(__dirname, '/expose/foo.js'),
+ bar: path.join(__dirname, '/expose/bar.js'),
+ main: path.join(__dirname, '/expose/main.js')
+};
+
+var sources = Object.keys(files).reduce(function (acc, file) {
+ acc[file] = fs.readFileSync(files[file], 'utf8');
+ return acc;
+}, {});
+
+var cache = {};
+cache[files.abc] = {
+ source: sources.abc,
+ deps: {}
+};
+cache[files.xyz] = {
+ source: sources.xyz,
+ deps: {'../foo': files.foo}
+};
+cache[files.foo] = {
+ source: sources.foo,
+ deps: {'./lib/abc': files.abc}
+};
+cache[files.bar] = {
+ source: sources.bar,
+ deps: {xyz: files.xyz}
+};
+cache[files.main] = {
+ source: sources.main,
+ deps: {
+ abc: files.abc,
+ xyz: files.xyz,
+ './bar': files.bar
+ }
+};
+
+test('preserves expose and entry with partial cache', function(t) {
+ t.plan(1);
+
+ var partialCache = copy(cache);
+ delete partialCache[files.bar];
+
+ var p = parser({ cache: partialCache });
+ p.write({ id: 'abc', file: files.abc, expose: 'abc' });
+ p.write({ id: 'xyz', file: files.xyz, expose: 'xyz' });
+ p.end({ id: 'main', file: files.main, entry: true });
+
+ var rows = [];
+ p.on('data', function (row) { rows.push(row); });
+ p.on('end', function () {
+ t.same(rows.sort(cmp), [
+ {
+ id: files.bar,
+ file: files.bar,
+ source: sources.bar,
+ deps: {xyz: files.xyz}
+ },
+ {
+ file: files.foo,
+ id: files.foo,
+ source: sources.foo,
+ deps: {'./lib/abc': files.abc}
+ },
+ {
+ id: 'abc',
+ file: files.abc,
+ source: sources.abc,
+ deps: {},
+ entry: true,
+ expose: 'abc'
+ },
+ {
+ id: 'main',
+ file: files.main,
+ source: sources.main,
+ deps: {
+ './bar': files.bar,
+ abc: files.abc,
+ xyz: files.xyz
+ },
+ entry: true
+ },
+ {
+ id: 'xyz',
+ file: files.xyz,
+ source: sources.xyz,
+ deps: {'../foo': files.foo},
+ entry: true,
+ expose: 'xyz'
+ }
+ ].sort(cmp));
+ });
+});
+
+function cmp (a, b) { return a.id < b.id ? -1 : 1 }
diff --git a/test/expose/bar.js b/test/expose/bar.js
new file mode 100644
index 0000000..31559ce
--- /dev/null
+++ b/test/expose/bar.js
@@ -0,0 +1 @@
+require('xyz');
diff --git a/test/expose/foo.js b/test/expose/foo.js
new file mode 100644
index 0000000..aa7d3b9
--- /dev/null
+++ b/test/expose/foo.js
@@ -0,0 +1 @@
+require('./lib/abc');
diff --git a/test/expose/lib/abc.js b/test/expose/lib/abc.js
new file mode 100644
index 0000000..d13b536
--- /dev/null
+++ b/test/expose/lib/abc.js
@@ -0,0 +1 @@
+console.log('abc');
diff --git a/test/expose/lib/xyz.js b/test/expose/lib/xyz.js
new file mode 100644
index 0000000..a44c530
--- /dev/null
+++ b/test/expose/lib/xyz.js
@@ -0,0 +1,2 @@
+require('../foo');
+console.log('xyz');
diff --git a/test/expose/main.js b/test/expose/main.js
new file mode 100644
index 0000000..00c0e24
--- /dev/null
+++ b/test/expose/main.js
@@ -0,0 +1,3 @@
+require('abc');
+require('xyz');
+require('./bar');
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-module-deps.git
More information about the Pkg-javascript-commits
mailing list