Make diff asynchronous

dev/git-series/gccdum
Matt Godbolt 7 years ago
parent 533216438f
commit a3e82b54ee

@ -62,7 +62,7 @@ console.log("properties hierarchy: " + propHierarchy)
// Define an ugly debug function
function debug_show_variable(variable_string_name) {
if (opts.propDebug) {
console.log("DEBUG:" + variable_string_name +" has value " + JSON.stringify(eval(variable_string_name)))
console.log("DEBUG:" + variable_string_name + " has value " + JSON.stringify(eval(variable_string_name)))
}
}
@ -78,8 +78,10 @@ var gccProps = props.propsFor("gcc-explorer");
// Read from gccexplorer's config the wdiff configuration
// that will be used to configure lib/diff.js
var wdiffConfig = {wdiffExe: gccProps('wdiff_exe', "wdiff"),
wdiffTmpDir: gccProps('wdiff_tmp_dir',"/tmp")};
var wdiffConfig = {
wdiffExe: gccProps('wdiff', "wdiff"),
maxOutput: gccProps("max-diff-output", 100000)
};
// Instantiate a function to access records concerning the chosen language
// in hidden object props.properties
@ -330,7 +332,7 @@ function getCompilerInfo(compilerInfo) {
}
// debug (seems to be displayed multiple times):
if (opts.propDebug) console.log("compiler options: "+ JSON.stringify(options,null,4));
if (opts.propDebug) console.log("compiler options: " + JSON.stringify(options, null, 4));
resolve(compilerInfo);
});

@ -11,5 +11,5 @@ optionsBlacklistRe=^(-W[alp],)?((-wrapper|-fplugin.*|-specs|-load|-plugin|(@.*)|
allowedShortUrlHostRe=^([a-z]+\.)?(xania|godbolt)\.org$
googleShortLinkRewrite=^https?://goo.gl/(.*)$|https://godbolt.org/g/$1
wdiff_exe=wdiff
wdiff_tmp_dir=/tmp
wdiff=wdiff
max-diff-output=100000

@ -1,5 +1,8 @@
var fs = require('fs');
var child_process = require('child_process');
var fs = require('fs'),
child_process = require('child_process'),
temp = require('temp'),
path = require('path'),
Promise = require('promise');
function cleanAndGetIndexes(text) {
var addRules = {
@ -136,48 +139,88 @@ function cleanAndGetIndexes(text) {
return {text: finalText, zones: zones};
}
function newTempDir() {
return new Promise(function (resolve, reject) {
temp.mkdir('gcc-explorer-diff', function (err, dirPath) {
if (err)
reject("Unable to open temp file: " + err);
else
resolve(dirPath);
});
});
}
var writeFile = Promise.denodeify(fs.writeFile);
function buildDiffHandler(config) {
var maxFileSize = config.maxOutput;
return function diffHandler(req, res) {
var before = req.body.before;
var after = req.body.after;
var error;
if (before === undefined) {
console.log("Warning : Bad request : wrong \"before\"");
//return next(new Error("Bad request : wrong \"before\""));
error = 'Warning : Bad request : wrong "before"';
console.log(error);
return next(new Error(error));
}
if (after === undefined) {
console.log("Warning : Bad request : wrong \"after\"");
//return next(new Error("Bad request : wrong \"after\""));
}
// TODO : make async the two creation of temp files + call to wdiff ?
var wdiffExe = config.wdiffExe;
var tempBeforePath = config.wdiffTmpDir + "/gcc-explorer-wdiff-before";
fs.writeFileSync(tempBeforePath, before);
var tempAfterPath = config.wdiffTmpDir + "/gcc-explorer-wdiff-after";
fs.writeFileSync(tempAfterPath, after);
// TODO : get rid of this buffer or calculate it...
var maxSize = 100000;
var wdiffResult = child_process.spawnSync(
wdiffExe,
[tempBeforePath, tempAfterPath],
{maxBuffer: 100000});
res.set('Content-Type', 'application/json');
var cleaned = cleanAndGetIndexes(wdiffResult.stdout.toString());
if (cleaned === null) {
res.end(JSON.stringify({
computedDiff: "Failed to clean the diff",
zones: null
}));
} else {
res.end(JSON.stringify({
computedDiff: cleaned.text,
zones: cleaned.zones
}));
error = 'Warning : Bad request : wrong "after"';
console.log(error);
return next(new Error(error));
}
var tempBeforePath, tempAfterPath;
newTempDir()
.then(function (tmpDir) {
tempBeforePath = path.join(tmpDir, "gcc-explorer-wdiff-before");
tempAfterPath = path.join(tmpDir, "gcc-explorer-wdiff-after");
return Promise.all(
writeFile(tempBeforePath, before),
writeFile(tempAfterPath, after)
);
})
.then(function () {
var truncated = false;
var stdout = "";
var child = child_process.spawn(config.wdiffExe, [tempBeforePath, tempAfterPath],
{maxBuffer: maxFileSize, detached: true});
child.stdout.on('data', function (data) {
if (truncated) return;
if (stdout.length > maxFileSize) {
stdout += "\n[Truncated]";
truncated = true;
child.kill();
return;
}
stdout += data;
});
return new Promise(function (resolve, reject) {
child.on('error', function (e) {
reject(e);
});
child.on('exit', function (code) {
resolve(stdout);
});
});
})
.then(function (output) {
var cleaned = cleanAndGetIndexes(output);
res.set('Content-Type', 'application/json');
if (cleaned === null) {
res.end(JSON.stringify({
computedDiff: "Failed to clean the diff",
zones: null
}));
} else {
res.end(JSON.stringify({
computedDiff: cleaned.text,
zones: cleaned.zones
}));
}
})
.catch(function (err) {
res.error(err);
});
};
}

Loading…
Cancel
Save