Skip to content

Commit

Permalink
Allow caching of compiler version and argument information to improve…
Browse files Browse the repository at this point in the history
… startup time
  • Loading branch information
apmorton committed May 29, 2019
1 parent 90aafb7 commit bf23550
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
"quote-props": ["error", "as-needed"]
},
"parserOptions": {
"ecmaVersion": 6
"ecmaVersion": 2017
}
}
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,4 @@ From oldest to newest contributor, we would like to thank:
- [Sebastian Staffa](https://github.com/Staff-d)
- [Andreas Jonson](https://github.com/andjo403)
- [Sam Clegg](https://github.com/sbc100)
- [Austin Morton](https://github.com/apmorton)
3 changes: 3 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

const startTime = new Date();

// Initialise options and properties. Don't load any handlers here; they
// may need an initialised properties library.
const nopt = require('nopt'),
Expand Down Expand Up @@ -286,6 +288,7 @@ aws.initConfig(awsProps)
_port = defArgs.port;
}
logger.info(` Listening on http://${defArgs.hostname || 'localhost'}:${_port}/`);
logger.info(` Startup duration: ${new Date() - startTime}ms`);
logger.info("=======================================");
server.listen(_port, defArgs.hostname);
}
Expand Down
18 changes: 17 additions & 1 deletion lib/base-compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,22 @@ class BaseCompiler {
return exec.execute(compiler, args, options);
}

getCompilerCacheKey(compiler, args, options) {
return {mtime: this.mtime, compiler, args, options};
}

async execCompilerCached(compiler, args, options) {
const key = this.getCompilerCacheKey(compiler, args, options);
let result = await this.env.compilerCacheGet(key);
if (!result) {
result = await exec.execute(compiler, args, options);
if (result.okToCache)
this.env.compilerCachePut(key, result);
}

return result;
}

getDefaultExecOptions() {
return {
timeoutMs: this.env.ceProps("compileTimeoutMs", 7500),
Expand Down Expand Up @@ -877,7 +893,7 @@ Please select another pass or change filters.`;
const execOptions = this.getDefaultExecOptions();
const versionFlag = this.compiler.versionFlag || '--version';
execOptions.timeoutMs = 0; // No timeout for --version. A sort of workaround for slow EFS/NFS on the prod site
return this.exec(this.compiler.exe, [versionFlag], execOptions);
return this.execCompilerCached(this.compiler.exe, [versionFlag], execOptions);
}

initialise() {
Expand Down
16 changes: 16 additions & 0 deletions lib/compilation-env.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class CompilationEnvironment {
this.cache = FromConfig.create(doCache === undefined || doCache ? this.ceProps('cacheConfig', '') : "");
this.executableCache = FromConfig.create(doCache === undefined ||
doCache ? this.ceProps('executableCacheConfig', '') : "");
this.compilerCache = FromConfig.create(doCache === undefined ||
doCache ? this.ceProps('compilerCacheConfig', '') : "");
this.compileQueue = new Queue(this.ceProps("maxConcurrentCompiles", 1), Infinity);
this.reportCacheEvery = this.ceProps("cacheReportEvery", 100);
this.multiarch = null;
Expand Down Expand Up @@ -89,6 +91,20 @@ class CompilationEnvironment {
return this.cache.put(key, JSON.stringify(result), creator);
}

async compilerCacheGet(object) {
const key = BaseCache.hash(object);
const result = await this.compilerCache.get(key);
if (!result.hit) {
return null;
}
return JSON.parse(result.data);
}

compilerCachePut(object, result, creator) {
const key = BaseCache.hash(object);
return this.compilerCache.put(key, JSON.stringify(result), creator);
}

executableGet(object, destinationFolder) {
const key = BaseCache.hash(object) + '_exec';
return this.executableCache.get(key).then((result) => {
Expand Down
6 changes: 3 additions & 3 deletions lib/compilers/argument-parsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class BaseParser {
}

static getOptions(compiler, helpArg) {
return compiler.exec(compiler.compiler.exe, [helpArg]).then(result => {
return compiler.execCompilerCached(compiler.compiler.exe, [helpArg]).then(result => {
let options = {};
if (result.code === 0) {
const optionFinder = /^\s*(--?[a-z0-9=+,[\]<>|-]*)\s*(.*)/i;
Expand Down Expand Up @@ -153,7 +153,7 @@ class ISPCParser extends BaseParser {
}

static getOptions(compiler, helpArg) {
return compiler.exec(compiler.compiler.exe, [helpArg]).then(result => {
return compiler.execCompilerCached(compiler.compiler.exe, [helpArg]).then(result => {
let options = {};
if (result.code === 0) {
const optionFinder = /^\s*\[(--?[a-z0-9=+,{}\s[\]<>|-]*)\]\s*(.*)/i;
Expand Down Expand Up @@ -231,7 +231,7 @@ class VCParser extends BaseParser {
}

static getOptions(compiler, helpArg) {
return compiler.exec(compiler.compiler.exe, [helpArg]).then(result => {
return compiler.execCompilerCached(compiler.compiler.exe, [helpArg]).then(result => {
let options = {};
if (result.code === 0) {
const optionFinder = /^\s*(\/[a-z0-9=:+#.,[\]{}<>|_-]*)\s*(.*)/i;
Expand Down
9 changes: 3 additions & 6 deletions lib/handlers/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,9 @@ class CompileHandler {
logger.debug(`${compiler.id} is unchanged`);
return cached;
}
return new this.factories[type](compiler, this.compilerEnv)
.initialise()
.then(compiler => {
if (compiler) compiler.mtime = res.mtime;
return compiler;
});
const compilerObj = new this.factories[type](compiler, this.compilerEnv);
compilerObj.mtime = res.mtime;
return compilerObj.initialise();
})
.catch(err => {
logger.warn(`Unable to stat ${compiler.id} compiler binary: `, err);
Expand Down
1 change: 1 addition & 0 deletions test/compilers/argument-parsers-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ function makeCompiler(stdout, stderr, code) {
const env = new CompilationEnvironment(compilerProps);
const compiler = new FakeCompiler({lang: languages['c++'].id, remote: true}, env);
compiler.exec = () => Promise.resolve({code: code, stdout: stdout || "", stderr: stderr || ""});
compiler.execCompilerCached = compiler.exec;
compiler.possibleArguments = new CompilerArguments("g82");
return compiler;
}
Expand Down

0 comments on commit bf23550

Please sign in to comment.