[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