Skip to content

Commit

Permalink
Agents must have a temp dir of their own, or risk interference with o…
Browse files Browse the repository at this point in the history
…ther agents in other threads
  • Loading branch information
rwaldron committed Oct 23, 2018
1 parent 5973ae2 commit af6832b
Show file tree
Hide file tree
Showing 8 changed files with 310 additions and 273 deletions.
6 changes: 4 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
"sourceType": "module",
"ecmaVersion": 2017
},
"globals": {
"assert": true,
Expand All @@ -16,6 +17,7 @@
"sinon": true
},
"rules": {
"no-console": [0]
"no-console": [0],
"no-empty-pattern": [0]
}
}
31 changes: 22 additions & 9 deletions lib/ConsoleAgent.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,27 @@
const fs = require('fs');
const path = require('path');
const cp = require('child_process');
const temp = require('temp');
const recast = require('recast');
const uniqueTempDir = require('unique-temp-dir');

const Agent = require('./Agent.js');
const ErrorParser = require('./parseError.js');
const Agent = require('./Agent');
const ErrorParser = require('./parseError');
const inception = require('./inception');
const {getDependencies, hasModuleSpecifier, rawSource} = require('./dependencies.js');
const writeSources = require('./write-sources.js');
const writeSources = require('./write-sources');
const {
getDependencies,
// escapeModuleSpecifier,
hasModuleSpecifier,
rawSource
} = require('./dependencies');

const cpSym = Symbol('cp');
const tpSym = Symbol('tp');

function generateTempFileName() {
const now = Date.now();
return `f-${now}-${process.pid}-${(Math.random() * 0x100000000 + 1).toString(36)}.js`;
}

class ConsoleAgent extends Agent {
constructor(options) {
Expand All @@ -21,6 +32,7 @@ class ConsoleAgent extends Agent {
// Promise for the child process created by the most
// recent invocation of `evalScript`
this[cpSym] = null;
this[tpSym] = uniqueTempDir();
}

createChildProcess(args = [], options = {}) {
Expand All @@ -32,8 +44,8 @@ class ConsoleAgent extends Agent {
}

evalScript(code, options = {}) {
let tempfile = temp.path({ suffix: '.js' });
let temppath = path.dirname(tempfile);
let tempfile = path.join(this[tpSym], generateTempFileName());
let temppath = this[tpSym];

let hasDependencies = false;
let sourcecode;
Expand Down Expand Up @@ -113,12 +125,13 @@ class ConsoleAgent extends Agent {
// 3. Add the prepped source to list of sources that will be written
//
dependencies.forEach(file => {
let absname = path.join(temppath, file);
let rawsource = rawSource.get(path.basename(file));
let jspart = rawsource.split(/\/\*---[\r\n]+[\S\s]*[\r\n]+---\*\//)[1];

if (path.join(temppath, file) !== tempfile) {
if (absname !== tempfile) {
sources.push([
path.join(temppath, file),
absname,
`${preamble}\n${jspart ? jspart : rawsource}`
]);
}
Expand Down
4 changes: 4 additions & 0 deletions lib/dependencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ const fs = require('fs');
const path = require('path');
const rawSourceCache = new Map();

function escapeModuleSpecifier(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

function hasModuleSpecifier(source) {
const dynamicImport = /import\((\s*)('(.+)'|"(.*)")(\s*)\)/g.exec(source);
Expand Down Expand Up @@ -73,6 +76,7 @@ function getDependencies(file, accum = []) {
}

module.exports = {
escapeModuleSpecifier,
getDependencies,
hasModuleSpecifier,
rawSource: {
Expand Down
14 changes: 14 additions & 0 deletions lib/promisify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = function(api) {
return function(...args) {
return new Promise((resolve, reject) => {
args.push((error, result) => {
if (error) {
return reject(error);
}
return resolve(result);
});
api(...args);
});
};
};

39 changes: 23 additions & 16 deletions lib/write-sources.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
'use strict';

const fs = require('fs');
const path = require('path');

const promisify = require('./promisify');
const mkdir = promisify(fs.mkdir);
const stat = promisify(fs.stat);
const writeFile = promisify(fs.writeFile);

module.exports = function(sources) {
module.exports = async function(sources) {
let {0: [file]} = sources;
let dir = path.dirname(file);

await safeMkdir(dir);
/*
first: path to output file
second: contents
*/
return Promise.all(
// TODO: Can we use built-in fs-promise?
return await Promise.all(
sources.map(args => writeFile(...args))
);
};

function promisify(api) {
return function(...args) {
return new Promise(function(resolve, reject) {
args.push(function(error, result) {
if (error) {
return reject(error);
}
return resolve(result);
});
api(...args);
});
};
async function safeMkdir(dir) {
try {
await stat(dir);
} catch (error) {
if (error.code === 'ENOENT') {
try {
await mkdir(dir);
} catch ({}) {
// suppressed?
}
}
}
}

Loading

0 comments on commit af6832b

Please sign in to comment.