-
Notifications
You must be signed in to change notification settings - Fork 178
/
Copy pathDockerTracer.ts
66 lines (62 loc) · 2.16 KB
/
DockerTracer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import path from 'path';
import { Release, Tracer } from 'tracers/Tracer';
import express from 'express';
import uuid from 'uuid';
import fs from 'fs-extra';
import { memoryLimit, timeLimit } from 'config/constants';
import { codesDir } from 'config/paths';
import { execute } from 'utils/misc';
export class DockerTracer extends Tracer {
private readonly directory: string;
private readonly imageName: string;
constructor(lang: string) {
super(lang);
this.directory = path.resolve(__dirname, lang);
this.imageName = `tracer-${this.lang}`;
}
build(release: Release) {
const {tag_name} = release;
return execute(`docker build -t ${this.imageName} . --build-arg tag_name=${tag_name}`, {
cwd: this.directory,
stdout: process.stdout,
stderr: process.stderr,
});
}
route(router: express.Router) {
router.post(`/${this.lang}`, (req, res, next) => {
const {code} = req.body;
const tempPath = path.resolve(codesDir, uuid.v4());
fs.outputFile(path.resolve(tempPath, `Main.${this.lang}`), code)
.then(() => {
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/visualization',
`-v=${tempPath}:/usr/visualization:rw`,
`-m=${memoryLimit}m`,
'-e ALGORITHM_VISUALIZER=1',
this.imageName,
].join(' ')).catch(error => {
if (killed) throw new Error('Time Limit Exceeded');
throw error;
}).finally(() => clearTimeout(timer));
})
.then(() => new Promise((resolve, reject) => {
const visualizationPath = path.resolve(tempPath, 'visualization.json');
res.sendFile(visualizationPath, (err: any) => {
if (err) return reject(new Error('Visualization Not Found'));
resolve();
});
}))
.catch(next)
.finally(() => fs.remove(tempPath));
});
}
}