Skip to content

Commit 9dc4e19

Browse files
committed
add support for mode parameter for POST /runs
1 parent 45877f4 commit 9dc4e19

File tree

5 files changed

+98
-11
lines changed

5 files changed

+98
-11
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"@types/amqplib": "^0.5.4",
1212
"amqplib": "^0.5.2",
1313
"apidoc": "^0.17.6",
14+
"axios": "^0.18.0",
1415
"base-64": "^0.1.0",
1516
"debug": "^4.0.0",
1617
"express": "^4.16.2",

src/routes/api/run.ts

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import {Response, Router, Request} from 'express'
2+
import axios from 'axios'
3+
24
import {SubmissionAttributes, Submissions} from '../../db/models'
35
import {RunJob, queueJob, successListener} from '../../rabbitmq/jobqueue'
46
import {isInvalidRunRequest} from '../../validators/SubmissionValidators'
@@ -9,7 +11,9 @@ const route: Router = Router()
911
export type RunRequestBody = {
1012
source: string, //Base64 encoded
1113
lang: string,
12-
stdin: string
14+
stdin: string,
15+
mode: string,
16+
callback?: string
1317
}
1418
export interface RunRequest extends Request {
1519
body: RunRequestBody
@@ -21,7 +25,62 @@ export interface RunResponse {
2125
stderr: string
2226
}
2327

24-
const runPool: {[x: number]: Response} = {}
28+
export type RunPoolElement = {
29+
mode: string,
30+
res: Response,
31+
callback?: string
32+
}
33+
34+
const runPool: {[x: number]: RunPoolElement} = {}
35+
36+
const handleTimeoutForSubmission = function (submissionId: number) {
37+
const job = runPool[submissionId]
38+
const errorResponse = {
39+
id: submissionId,
40+
code: 408,
41+
message: "Compile/Run timed out",
42+
}
43+
44+
switch (job.mode) {
45+
case 'sync':
46+
job.res.status(408).json(errorResponse)
47+
break;
48+
case 'callback':
49+
axios.post(job.callback, errorResponse)
50+
}
51+
}
52+
53+
const handleSuccessForSubmission = function (result: RunResponse) {
54+
const job = runPool[result.id]
55+
switch (job.mode) {
56+
case 'sync':
57+
job.res.status(200).json(result)
58+
break;
59+
case 'callback':
60+
// send a post request to callback
61+
axios.post(job.callback, result)
62+
break;
63+
}
64+
}
65+
66+
/**
67+
* Returns a runPoolElement for request
68+
*/
69+
const getRunPoolElement = function (body: RunRequestBody, res: Response): RunPoolElement {
70+
switch (body.mode) {
71+
case 'sync':
72+
return ({
73+
mode: 'sync',
74+
res
75+
})
76+
case 'callback':
77+
return ({
78+
mode: 'callback',
79+
res,
80+
callback: body.callback
81+
})
82+
}
83+
}
2584

2685
/**
2786
* @api {post} /runs POST /runs
@@ -70,19 +129,22 @@ route.post('/', (req, res, next) => {
70129
lang: req.body.lang,
71130
stdin: req.body.stdin
72131
})
132+
73133
// Put into pool and wait for judge-worker to respond
74-
runPool[submission.id] = res
134+
runPool[submission.id] = getRunPoolElement(req.body, res)
135+
75136
setTimeout(() => {
76137
if (runPool[submission.id]) {
77-
runPool[submission.id].status(408).json({
78-
id: submission.id,
79-
code: 408,
80-
message: "Compile/Run timed out",
81-
})
138+
handleTimeoutForSubmission(submission.id)
82139
delete runPool[submission.id]
83140
}
84141
}, config.RUN.TIMEOUT)
85142

143+
switch (req.body.mode) {
144+
case 'callback':
145+
res.sendStatus(200)
146+
}
147+
86148
}).catch(err => {
87149
res.status(501).json({
88150
code: 501,
@@ -97,7 +159,7 @@ route.post('/', (req, res, next) => {
97159
*/
98160
successListener.on('success', (result: RunResponse) => {
99161
if (runPool[result.id]) {
100-
runPool[result.id].status(200).json(result)
162+
handleSuccessForSubmission(result)
101163
delete runPool[result.id]
102164
}
103165
Submissions.update({

src/validators/SubmissionValidators.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ export function isInvalidRunRequest(req: Request): Error | boolean {
1212
if (!req.body.stdin) {
1313
req.body.stdin = ''
1414
}
15+
if (!req.body.mode) {
16+
req.body.mode = 'sync'
17+
}
18+
if (!['sync', 'callback'].includes(req.body.mode)) {
19+
return new Error('Mode must be one of sync, callback')
20+
}
21+
if (req.body.mode === 'callback' && !req.body.callback) {
22+
return new Error('Must specify a callback for callback mode')
23+
}
1524

1625
return false
1726
}

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"compilerOptions": {
33
"module": "commonjs",
4-
"target": "es2015",
4+
"target": "es2016",
55
"moduleResolution": "node",
66
"allowSyntheticDefaultImports": true,
77
"sourceMap": true,

yarn.lock

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,14 @@ aws4@^1.6.0:
365365
version "1.6.0"
366366
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
367367

368+
axios@^0.18.0:
369+
version "0.18.0"
370+
resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102"
371+
integrity sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=
372+
dependencies:
373+
follow-redirects "^1.3.0"
374+
is-buffer "^1.1.5"
375+
368376
balanced-match@^1.0.0:
369377
version "1.0.0"
370378
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@@ -721,7 +729,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
721729
dependencies:
722730
ms "2.0.0"
723731

724-
debug@3.1.0, debug@^3.0.0, debug@^3.1.0:
732+
debug@3.1.0, debug@=3.1.0, debug@^3.0.0, debug@^3.1.0:
725733
version "3.1.0"
726734
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
727735
dependencies:
@@ -1026,6 +1034,13 @@ find-up@^2.1.0:
10261034
dependencies:
10271035
locate-path "^2.0.0"
10281036

1037+
follow-redirects@^1.3.0:
1038+
version "1.6.1"
1039+
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.6.1.tgz#514973c44b5757368bad8bddfe52f81f015c94cb"
1040+
integrity sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ==
1041+
dependencies:
1042+
debug "=3.1.0"
1043+
10291044
for-in@^1.0.1, for-in@^1.0.2:
10301045
version "1.0.2"
10311046
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"

0 commit comments

Comments
 (0)