Skip to content

Commit 1f721a6

Browse files
authored
Merge pull request #21 from alias-rahil/dev
fix: a part of #15 is fixed
2 parents 7154261 + 072dd4c commit 1f721a6

File tree

18 files changed

+122
-125
lines changed

18 files changed

+122
-125
lines changed

examples/worker.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Worker } from '../src/CodeExecutor';
1+
import { Worker, languages } from '../src/CodeExecutor';
2+
import logger from '../src/utils/logger';
23

34
/**
45
* name, redis, folderPath, default folderPath is /tmp/code-exec
@@ -8,6 +9,8 @@ import { Worker } from '../src/CodeExecutor';
89
const worker = new Worker('myExecutor', 'redis://127.0.0.1:6379');
910

1011
async function main() {
12+
logger.info(languages);
13+
1114
/* array of languages is optional argument */
1215
await worker.build(['Python', 'Bash']);
1316

@@ -16,6 +19,8 @@ async function main() {
1619
worker.pause();
1720

1821
worker.resume();
22+
23+
// worker.stop();
1924
}
2025

2126
main();

package-lock.json

Lines changed: 8 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
},
3232
"homepage": "https://github.com/csivitu/code-executor#readme",
3333
"devDependencies": {
34+
"@types/dockerode": "^2.5.34",
35+
"@types/randomstring": "^1.1.6",
36+
"@types/uuid": "^8.3.0",
3437
"@types/bull": "^3.14.2",
3538
"@types/node": "^14.6.3",
3639
"@typescript-eslint/eslint-plugin": "^4.0.1",
@@ -50,9 +53,6 @@
5053
}
5154
},
5255
"dependencies": {
53-
"@types/dockerode": "^2.5.34",
54-
"@types/randomstring": "^1.1.6",
55-
"@types/uuid": "^8.3.0",
5656
"bull": "^3.18.0",
5757
"del": "^6.0.0",
5858
"dockerode": "^3.2.1",

src/CodeExecutor.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { v4 as uuid } from 'uuid';
33

44
import { CodeParams, Result } from './models/models';
55
import logger from './utils/logger';
6+
import { extension } from './utils/findExtension';
7+
8+
const languages = Object.keys(extension);
69

710
export default class CodeExecutor {
811
private queue: Bull.Queue;
@@ -44,3 +47,5 @@ export default class CodeExecutor {
4447
}
4548

4649
export { default as Worker } from './Worker';
50+
51+
export { languages };

src/Runner.ts

Lines changed: 28 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
import Docker from 'dockerode';
2-
import path from 'path';
3-
import { performance } from 'perf_hooks';
2+
import {
3+
performance,
4+
} from 'perf_hooks';
45
import del from 'del';
5-
import writeToFile from './utils/writeToFile';
6-
import generateFolder from './utils/generateFolder';
76
import decodeBase64 from './utils/decodeBase64';
87
import logger from './utils/logger';
9-
import findExtension from './utils/findExtension';
108
import {
119
TestCase,
1210
Result,
1311
Tests,
1412
} from './models/models';
1513
import getOutput from './utils/getOutput';
14+
import saveCode from './utils/saveCode';
1615

1716
interface RunnerOpts {
1817
id: string;
@@ -31,30 +30,6 @@ export default class Runner {
3130
this.docker = docker;
3231
}
3332

34-
private static async saveCode(
35-
folderPath: string,
36-
code: string,
37-
testCases: TestCase[],
38-
base64: boolean,
39-
language: string,
40-
): Promise < string > {
41-
const folder = await generateFolder(folderPath);
42-
const extension = findExtension(language);
43-
const promisesToKeep = [(base64)
44-
? writeToFile(path.join(folder, `code.${extension}`), decodeBase64(code))
45-
: writeToFile(path.join(folder, `code.${extension}`), code),
46-
];
47-
for (let i = 0; i < testCases.length; i += 1) {
48-
const [input, output] = (base64)
49-
? [decodeBase64(testCases[i].input), decodeBase64(testCases[i].output)]
50-
: [testCases[i].input, testCases[i].output];
51-
promisesToKeep.push(writeToFile(path.join(folder, `in${i}.txt`), input));
52-
promisesToKeep.push(writeToFile(path.join(folder, `out${i}.txt`), output));
53-
}
54-
await Promise.all(promisesToKeep);
55-
return folder;
56-
}
57-
5833
async run({
5934
id,
6035
tag,
@@ -65,37 +40,38 @@ export default class Runner {
6540
language,
6641
timeout,
6742
}: RunnerOpts): Promise < Result > {
68-
const Path = await Runner.saveCode(folderPath, code, testCases, base64, language);
69-
const container = await this.docker.createContainer({
70-
Image: tag,
71-
Cmd: ['bash', '/start.sh', `${testCases.length}`, `${timeout}`],
72-
HostConfig: {
73-
Mounts: [{
74-
Source: Path,
75-
Target: '/app',
76-
Type: 'bind',
77-
}],
78-
},
79-
});
80-
43+
const Paths = await saveCode(folderPath, code, testCases, base64, language);
44+
const promisesToKeep: Array<Promise<Array<object>>> = [];
45+
for (let i = 0; i < Paths.length; i += 1) {
46+
promisesToKeep.push(this.docker.run(tag, ['bash', '/start.sh', `${i}`, `${timeout}`], null, {
47+
HostConfig: {
48+
AutoRemove: true,
49+
Mounts: [{
50+
Source: Paths[i],
51+
Target: '/app',
52+
Type: 'bind',
53+
}],
54+
},
55+
}));
56+
}
8157
logger.info(`Starting process ${id}`);
82-
8358
const t0 = performance.now();
84-
await container.start();
85-
await container.wait();
59+
await Promise.all(promisesToKeep);
8660
const t1 = performance.now();
61+
logger.info(`Process ${id} completed in ${(t1 - t0) / 1000} seconds`);
8762

88-
logger.info(`Process ${id} completed in ${t1 / 1000 - t0 / 1000} seconds`);
89-
90-
container.remove();
91-
const [output, runTime, error, exitCodes] = await getOutput(Path, testCases.length);
92-
del(Path, {
93-
force: true,
63+
const [output, runTime, error, exitCodes] = await getOutput(Paths, testCases.length);
64+
Paths.forEach((Path) => {
65+
del(Path, {
66+
force: true,
67+
});
9468
});
9569

9670
const tests: Tests[] = [];
9771
for (let i = 0; i < testCases.length; i += 1) {
98-
const expectedOutput = testCases[i].output;
72+
const expectedOutput = (base64)
73+
? decodeBase64(testCases[i].output)
74+
: testCases[i].output;
9975
const obtainedOutput = output[i].toString();
10076
const time = runTime[i].toString().split('\n');
10177
const exitCode = parseInt(exitCodes[i].toString(), 10);

src/Worker.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,8 @@ export default class Worker {
6464
resume() {
6565
this.queue.resume();
6666
}
67+
68+
stop() {
69+
this.queue.close();
70+
}
6771
}

src/langs/Bash/start.sh

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
END=$1
2-
for ((i=0;i<END;i++))
3-
do
1+
i=$1
42
date +%s%N > /app/time$i.txt
5-
timeout $2 bash -c "(cat /app/in$i.txt | bash /app/code.sh) 2> /app/error$i.txt 1> /app/output$i.txt"
3+
timeout $2 bash -c "(cat /app/in$i.txt | bash /app/Main.sh) 2> /app/error$i.txt 1> /app/output$i.txt"
64
echo $? > /app/exitCode$i.txt
7-
date +%s%N >> /app/time$i.txt
8-
done
5+
date +%s%N >> /app/time$i.txt

src/langs/C/start.sh

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
END=$1
2-
for ((i=0;i<END;i++))
3-
do
1+
i=$1
42
date +%s%N > /app/time$i.txt
5-
timeout $2 bash -c "(cat /app/in$i.txt | gcc -o /app/code /app/code.c -lm && ./app/code ) 2> /app/error$i.txt 1> /app/output$i.txt"
3+
timeout $2 bash -c "( cat /app/in$i.txt | ( gcc -o /app/Main /app/Main.c -pthread -lm && /app/Main ) ) 2> /app/error$i.txt 1> /app/output$i.txt"
64
echo $? > /app/exitCode$i.txt
7-
date +%s%N >> /app/time$i.txt
8-
done
5+
date +%s%N >> /app/time$i.txt

src/langs/Cplusplus/start.sh

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
END=$1
2-
for ((i=0;i<END;i++))
3-
do
1+
i=$1
42
date +%s%N > /app/time$i.txt
5-
timeout $2 bash -c "(cat /app/in$i.txt | g++ -o /app/code /app/code.cpp && ./app/code ) 2> /app/error$i.txt 1> /app/output$i.txt"
3+
timeout $2 bash -c "( cat /app/in$i.txt | ( g++ -o /app/Main /app/Main.cpp -pthread -lm && /app/Main ) ) 2> /app/error$i.txt 1> /app/output$i.txt"
64
echo $? > /app/exitCode$i.txt
7-
date +%s%N >> /app/time$i.txt
8-
done
5+
date +%s%N >> /app/time$i.txt

src/langs/Java/start.sh

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
END=$1
2-
for ((i=0;i<END;i++))
3-
do
1+
i=$1
42
date +%s%N > /app/time$i.txt
5-
timeout $2 bash -c "(cat /app/in$i.txt | javac /app/Code.java) 2> /app/error$i.txt 1> /app/output$i.txt"
3+
timeout $2 bash -c "( cat /app/in$i.txt | ( javac /app/Main.java && java Main ) ) 2> /app/error$i.txt 1> /app/output$i.txt"
64
echo $? > /app/exitCode$i.txt
7-
date +%s%N >> /app/time$i.txt
8-
done
5+
date +%s%N >> /app/time$i.txt

0 commit comments

Comments
 (0)