提交 27044d98 编写于 作者: J Jason Park

Bring compiling/running code parts from tracers repository

上级 b539553e
export {};
\ No newline at end of file
const memoryLimit = 256; // in megabytes
const timeLimit = 5000; // in milliseconds
export {
memoryLimit,
timeLimit,
};
......@@ -5,7 +5,6 @@ import fs from 'fs-extra';
import removeMarkdown from 'remove-markdown';
const execute = (command, cwd, { stdout = process.stdout, stderr = process.stderr } = {}) => new Promise((resolve, reject) => {
if (!cwd) return reject(new Error('CWD Not Specified'));
const child = child_process.exec(command, { cwd }, (error, stdout, stderr) => {
if (error) return reject(error.code ? new Error(stderr) : error);
resolve(stdout);
......
......@@ -29,4 +29,4 @@ router.route('/response')
router.route('/destroy')
.get(destroy);
export default router;
\ No newline at end of file
export default router;
import express from 'express';
import fs from 'fs-extra';
import Promise from 'bluebird';
import uuid from 'uuid';
import path from 'path';
import { GitHubApi } from '/apis';
import { execute } from '/common/util';
import webhook from '/common/webhook';
import { ImageBuilder, WorkerBuilder } from '/tracers';
import { memoryLimit, timeLimit } from '/common/config';
const router = express.Router();
const repoPath = path.resolve(__dirname, '..', 'public', 'tracers');
const getCodesPath = (...args) => path.resolve(__dirname, '..', 'public', 'codes', ...args);
const getJsWorker = (req, res, next) => {
res.sendFile(path.resolve(repoPath, 'src', 'languages', 'js', 'tracers', 'build', 'tracers.js'));
};
const trace = lang => (req, res, next) => {
const { code } = req.body;
const tempPath = getCodesPath(uuid.v4());
const tempPath = path.resolve(__dirname, '..', 'public', 'codes', uuid.v4());
const tracesPath = path.resolve(tempPath, 'traces.json');
fs.outputFile(path.resolve(tempPath, `Main.${lang}`), code)
.then(() => execute(`./bin/compile ${lang} ${tempPath}`, repoPath, { stdout: null, stderr: null }))
.then(() => execute(`./bin/run ${lang} ${tempPath}`, repoPath, { stdout: null, stderr: null }))
.then(() => res.sendFile(path.resolve(tempPath, 'traces.json')))
.then(() => {
const builder = builderMap[lang];
const containerName = uuid.v4();
let killed = false;
const timer = setTimeout(() => {
execute(`docker kill ${containerName}`).then(() => {
killed = true;
});
}, timeLimit);
return execute([
'docker run --rm',
`--name=${containerName}`,
'-w=/usr/tracer',
`-v=${tempPath}:/usr/tracer:rw`,
`-m=${memoryLimit}m`,
builder.imageName,
].join(' ')).catch(error => {
if (killed) throw new Error('Time Limit Exceeded');
throw error;
}).finally(() => clearTimeout(timer));
})
.then(() => fs.pathExists(tracesPath))
.then(exists => {
if (!exists) throw new Error('Traces Not Found');
res.sendFile(tracesPath);
})
.catch(next)
.finally(() => fs.remove(tempPath));
};
const buildRelease = release => (
fs.pathExistsSync(repoPath) ?
execute(`git fetch && ! git diff-index --quiet ${release.target_commitish} -- ':!package-lock.json'`, repoPath) :
execute(`git clone https://github.com/algorithm-visualizer/tracers.git ${repoPath}`, __dirname)
).then(() => execute(`git reset --hard ${release.target_commitish} && npm install && npm run build && ./bin/build`, repoPath));
const builderMap = {
js: new WorkerBuilder(),
cpp: new ImageBuilder('cpp'),
java: new ImageBuilder('java'),
};
GitHubApi.getLatestRelease('algorithm-visualizer', 'tracers').then(buildRelease).catch(console.error);
Promise.map(Object.keys(builderMap), lang => {
const builder = builderMap[lang];
return GitHubApi.getLatestRelease('algorithm-visualizer', `tracers.${lang}`).then(builder.build);
}).catch(console.error);
webhook.on('tracers', (event, data) => {
switch (event) {
case 'release':
buildRelease(data.release).catch(console.error);
break;
webhook.on('release', (repo, data) => {
const result = /^tracers\.(\w+)$/.exec(repo);
if (result) {
const [, lang] = result;
const builder = builderMap[lang];
builder.build(data.release).catch(console.error);
}
});
router.route('/js')
.get(getJsWorker);
router.route('/java')
.post(trace('java'));
router.route('/cpp')
.post(trace('cpp'));
Object.keys(builderMap).forEach(lang => {
const builder = builderMap[lang];
if (builder instanceof ImageBuilder) {
router.post(`/${lang}`, trace(lang));
} else if (builder instanceof WorkerBuilder) {
router.get(`/${lang}`, (req, res) => res.sendFile(builder.workerPath));
}
});
export default router;
import path from 'path';
import { execute } from '/common/util';
class ImageBuilder {
constructor(lang) {
this.lang = lang;
this.directory = path.resolve(__dirname, lang);
this.imageName = `tracer-${this.lang}`;
this.build = this.build.bind(this);
}
build(release) {
const { tag_name } = release;
return execute(`docker build -t ${this.imageName} . --build-arg tag_name=${tag_name}`, this.directory);
}
}
export default ImageBuilder;
import path from 'path';
class WorkerBuilder {
constructor() {
this.workerPath = path.resolve(__dirname, 'js', 'worker.js');
this.build = this.build.bind(this);
}
build(release) {
}
}
export default WorkerBuilder;
FROM rikorose/gcc-cmake
ARG tag_name
RUN curl --create-dirs -o /usr/local/include/nlohmann/json.hpp -L "https://github.com/nlohmann/json/releases/download/v3.1.2/json.hpp" \
&& curl --create-dirs -o /usr/tmp/algorithm-visualizer.tar.gz -L "https://github.com/algorithm-visualizer/tracers.cpp/archive/${tag_name}.tar.gz" \
&& cd /usr/tmp \
&& mkdir algorithm-visualizer \
&& tar xvzf algorithm-visualizer.tar.gz -C algorithm-visualizer --strip-components=1 \
&& cd /usr/tmp/algorithm-visualizer \
&& mkdir build \
&& cd build \
&& cmake .. \
&& make install
CMD g++ Main.cpp -o Main -O2 -std=c++11 \
&& ./Main
export { default as ImageBuilder } from './ImageBuilder';
export { default as WorkerBuilder } from './WorkerBuilder';
FROM openjdk:8
ARG tag_name
RUN curl --create-dirs -o /usr/local/lib/algorithm-visualizer.jar -L "https://github.com/algorithm-visualizer/tracers.java/releases/download/${tag_name}/algorithm-visualizer.jar"
CMD javac -cp /usr/local/lib/algorithm-visualizer.jar Main.java \
&& java -cp /usr/local/lib/algorithm-visualizer.jar:. Main
importScripts('https://unpkg.com/algorithm-visualizer/dist/algorithm-visualizer.js');
importScripts('https://unpkg.com/babel-standalone@6/babel.min.js');
const sandbox = code => {
const require = name => ({ 'algorithm-visualizer': AlgorithmVisualizer }[name]); // fake require
eval(code);
};
onmessage = e => { // TODO: stop after the first delay() on the initial run
const lines = e.data.split('\n').map((line, i) => line.replace(/(.+\. *delay *)(\( *\))/g, `$1(${i})`));
const { code } = Babel.transform(lines.join('\n'), { presets: ['es2015'] });
sandbox(code);
postMessage(AlgorithmVisualizer.Tracer.traces);
};
......@@ -8,12 +8,13 @@ class BaseComponent extends React.Component {
}
handleError(error) {
console.error(error);
if (error.response) {
const { data, statusText } = error.response;
const message = data ? typeof data === 'string' ? data : JSON.stringify(data) : statusText;
console.error(message);
this.props.showErrorToast(message);
} else {
console.error(error.message);
this.props.showErrorToast(error.message);
}
}
......
......@@ -90,6 +90,7 @@ class Player extends BaseComponent {
this.handleError(error);
});
} else {
this.setState({ building: false });
this.handleError(new Error('Language Not Supported'));
}
}
......
#include "LogTracer.h"
#include "algorithm-visualizer/LogTracer.h"
int main() {
LogTracer logTracer = LogTracer("Scratch Paper");
......
import org.algorithm_visualizer.tracers.*;
import org.algorithm_visualizer.*;
class Main {
public static void main(String[] args) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册