Skip to content

Commit 086751e

Browse files
committed
Add memory/time limits
1 parent 3ac076d commit 086751e

File tree

9 files changed

+46
-17
lines changed

9 files changed

+46
-17
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
66

77
## [Unreleased]
88

9+
## [2.0.5]
10+
### Added
11+
- Add memory/time limits
12+
913
## [2.0.4]
1014
### Fixed
1115
- Load limits from /common/config

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@algorithm-visualizer/tracer-generator",
3-
"version": "2.0.4",
3+
"version": "2.0.5",
44
"description": "Visualization Libraries for Algorithm Visualizer",
55
"scripts": {
66
"build": "node ./node_modules/webpack/bin/webpack --bail --progress --config webpack.config.js && chmod +x ./bin/*"
@@ -25,6 +25,7 @@
2525
"fs-extra": "^7.0.0",
2626
"gh-release": "^3.2.1",
2727
"uglifyjs-webpack-plugin": "^1.2.7",
28+
"uuid": "^3.3.2",
2829
"webpack": "^4.15.1",
2930
"webpack-cli": "^3.0.8",
3031
"webpack-node-externals": "^1.7.2"

src/common/config.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
const memoryLimit = 256; // in megabytes
2+
const timeLimit = 5000; // in milliseconds
13
const maxTraces = 1e6;
24
const maxTracers = 1e2;
35

46
export {
7+
memoryLimit,
8+
timeLimit,
59
maxTraces,
610
maxTracers,
711
};

src/common/util.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import Promise from 'bluebird';
22
import child_process from 'child_process';
33

4-
const execute = (command, cwd, { stdout = process.stdout, stderr = process.stderr } = {}) => new Promise((resolve, reject) => {
4+
const execute = (command, cwd) => new Promise((resolve, reject) => {
55
if (!cwd) return reject(new Error('CWD Not Specified'));
6-
const child = child_process.exec(command, { cwd }, (error, stdout, stderr) => {
7-
if (error) return reject(error.code ? new Error(stderr) : error);
8-
resolve(stdout);
6+
const child = child_process.exec(command, { cwd }, error => {
7+
if (error) return reject(error);
8+
resolve();
99
});
10-
if (stdout) child.stdout.pipe(stdout);
11-
if (stderr) child.stderr.pipe(stderr);
10+
child.stdout.pipe(process.stdout);
11+
child.stderr.pipe(process.stderr);
1212
});
1313

14+
const exit = error => process.exit(1);
15+
1416
export {
1517
execute,
18+
exit,
1619
};

src/executables/build.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import * as languages from '/languages';
22
import Promise from 'bluebird';
3+
import { exit } from '/common/util';
34

45
const { LANG } = process.env;
56
if (LANG) {
6-
languages[LANG].build().catch(() => process.exit(1));
7+
languages[LANG].build().catch(exit);
78
} else {
8-
Promise.each(Object.values(languages), language => language.build()).catch(() => process.exit(1));
9-
}
9+
Promise.each(Object.values(languages), language => language.build()).catch(exit);
10+
}

src/executables/compile.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as languages from '/languages';
2+
import { exit } from '/common/util';
23

34
const { LANG, TEMP_PATH } = process.env;
4-
languages[LANG].compile(TEMP_PATH).catch(() => process.exit(1));
5+
languages[LANG].compile(TEMP_PATH).catch(exit);

src/executables/release.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import ghRelease from 'gh-release';
22
import Promise from 'bluebird';
33
import { version } from '/package.json';
4-
import { execute } from '/common/util';
4+
import { execute, exit } from '/common/util';
55

66
const { GITHUB_TOKEN } = process.env;
77
const release = Promise.promisify(ghRelease);
@@ -23,4 +23,4 @@ release({ owner: 'algorithm-visualizer', repo: 'tracers', auth: { token: GITHUB_
2323
'cd ..',
2424
'rm -rf tracers.wiki',
2525
].join(' && '), __dirname))
26-
.catch(() => process.exit(1));
26+
.catch(exit);

src/executables/run.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as languages from '/languages';
2+
import { exit } from '/common/util';
23

34
const { LANG, TEMP_PATH } = process.env;
4-
languages[LANG].run(TEMP_PATH).catch(() => process.exit(1));
5+
languages[LANG].run(TEMP_PATH).catch(exit);

src/languages/Exeuter.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { execute } from '/common/util';
22
import Commander from '/languages/Commander';
3-
import { maxTracers, maxTraces } from '/common/config';
3+
import { maxTracers, maxTraces, memoryLimit, timeLimit } from '/common/config';
4+
import uuid from 'uuid';
45

56
class Executer extends Commander {
67
constructor({ name, compileCommand, runCommand }) {
@@ -12,17 +13,30 @@ class Executer extends Commander {
1213
}
1314

1415
execute(tempPath, command) {
15-
// TODO: memory limit + time limit + space limit?
16+
const containerName = uuid.v4();
17+
let timer = setTimeout(() => {
18+
timer = null;
19+
execute(`docker kill ${containerName}`, this.cwd);
20+
}, timeLimit);
1621
return execute([
1722
`docker run --rm`,
23+
`--name=${containerName}`,
1824
'-w=/usr/judge',
1925
`-v=$PWD/tracers:/usr/bin/tracers:ro`,
2026
`-v=${tempPath}:/usr/judge:rw`,
27+
`-m=${memoryLimit}m --memory-swap=${memoryLimit}m`, // TODO: needs to be tested on linux
2128
`-e MAX_TRACES=${maxTraces} -e MAX_TRACERS=${maxTracers}`,
2229
this.executerImageTag,
2330
'/bin/bash -c',
2431
`"${command}"`,
25-
].join(' '), this.cwd);
32+
].join(' '), this.cwd).catch(error => {
33+
if (timer) {
34+
clearTimeout(timer);
35+
} else {
36+
console.error('Time Limit Exceeded');
37+
}
38+
throw error;
39+
});
2640
}
2741

2842
compile(tempPath) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy