Skip to content

Commit f077ff9

Browse files
Merge pull request #70 from prabalsingh24/project-submission
Project submission
2 parents 9d3ede8 + 61c37b3 commit f077ff9

File tree

4 files changed

+136
-3
lines changed

4 files changed

+136
-3
lines changed

src/rabbitmq/jobqueue.ts

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,17 @@ export interface RunJob {
2626
scenario: string
2727
}
2828

29-
export type JudgeJob = RunJob | SubmissionJob
29+
export interface ProjectJob {
30+
id: number
31+
source: string,
32+
lang: string,
33+
problem: string,
34+
timelimit: number,
35+
scenario: string,
36+
submissionDirs: string
37+
}
38+
39+
export type JudgeJob = RunJob | SubmissionJob | ProjectJob
3040

3141
let jobQ = 'job_queue'
3242
let successQ = 'success_queue'
@@ -50,8 +60,17 @@ amqp.connect(`amqp://${config.AMQP.USER}:${config.AMQP.PASS}@${config.AMQP.HOST}
5060
jobChannel.consume(successQ, (msg) => {
5161
debug(`SUCCESS:CONSUME: msg.content = ${msg.content.toString()}`)
5262

53-
const payload = JSON.parse(msg.content.toString())
54-
const eventName = payload.testcases ? 'submit_result' : 'run_result'
63+
const payload = JSON.parse(msg.content.toString())
64+
let eventName;
65+
if (payload.testcases) {
66+
eventName = 'submit_result'
67+
}
68+
else if (payload.code && payload.score) {
69+
eventName = 'project_result'
70+
}
71+
else {
72+
eventName = 'run_result'
73+
}
5574

5675
successListener.emit(eventName, payload)
5776
jobChannel.ack(msg)

src/routes/api/project/controller.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { Request, Response } from 'express'
2+
import {ProjectJob, queueJob} from 'rabbitmq/jobqueue'
3+
import DB from 'models'
4+
import axios from 'axios'
5+
6+
type ProjectResponse = {
7+
id: number,
8+
stdout: string,
9+
stderr: string,
10+
time: number,
11+
code: number,
12+
score: number
13+
}
14+
type RunPoolElement = {
15+
res: Response
16+
}
17+
18+
const RunPool: { [x: number]: RunPoolElement } = {}
19+
20+
export default {
21+
async runPOST(req: Request, res: Response) {
22+
const mode = req.body.mode || 'sync'
23+
const job = await DB.submissions.create({
24+
lang: req.body.lang,
25+
start_time: new Date(),
26+
mode,
27+
callback: req.body.callback
28+
})
29+
30+
await queueJob(<ProjectJob>{
31+
id: job.id,
32+
source: req.body.submission,
33+
problem: req.body.problem,
34+
lang: req.body.lang,
35+
submissionDirs: req.body.submissionDirs,
36+
timelimit: req.body.timelimit,
37+
scenario: 'project'
38+
})
39+
40+
41+
if (['callback', 'poll'].includes(mode)) {
42+
return res.json({
43+
id: job.id
44+
})
45+
}
46+
47+
// if mode === 'sync'
48+
RunPool[job.id] = {
49+
res
50+
}
51+
},
52+
53+
async onSuccess(result: ProjectResponse) {
54+
const job = await DB.submissions.findById(result.id)
55+
job.results = result
56+
await job.save()
57+
58+
switch (job.mode) {
59+
case 'callback':
60+
await axios.post(job.callback, result)
61+
break
62+
case 'sync':
63+
RunPool[job.id].res.json(result)
64+
break
65+
}
66+
}
67+
}

src/routes/api/project/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Router } from 'express'
2+
import Controller from './controller'
3+
import Validator from './validators'
4+
import { successListener } from 'rabbitmq/jobqueue'
5+
6+
const router: Router = Router()
7+
const validator = new Validator()
8+
9+
router.post('/', validator.POST, Controller.runPOST)
10+
successListener.on('project_result', Controller.onSuccess)
11+
12+
export default router

src/routes/api/project/validators.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Handler } from 'express'
2+
import BaseValidator from 'validators/baseValidator'
3+
import * as Joi from '@hapi/joi'
4+
5+
export default class ProjectValidator extends BaseValidator {
6+
POST: Handler
7+
8+
constructor() {
9+
super()
10+
this.POST = this.requestValidator(this.POSTSchema)
11+
}
12+
13+
POSTSchema = Joi.object({
14+
problem: Joi
15+
.string()
16+
.uri()
17+
.required(),
18+
submission: Joi
19+
.string()
20+
.uri()
21+
.required(),
22+
submissionDirs: Joi
23+
.string()
24+
.required(),
25+
mode: Joi
26+
.string()
27+
.valid('sync', 'callback', 'poll'),
28+
callback: Joi
29+
.string()
30+
.uri()
31+
.when('mode', { is: 'callback', then: Joi.required() }),
32+
timelimit: Joi
33+
.number(),
34+
})
35+
}

0 commit comments

Comments
 (0)