11import { Response , Router , Request } from 'express'
2+ import axios from 'axios'
3+
24import { SubmissionAttributes , Submissions } from '../../db/models'
35import { RunJob , queueJob , successListener } from '../../rabbitmq/jobqueue'
46import { isInvalidRunRequest } from '../../validators/SubmissionValidators'
@@ -9,7 +11,9 @@ const route: Router = Router()
911export type RunRequestBody = {
1012 source : string , //Base64 encoded
1113 lang : string ,
12- stdin : string
14+ stdin : string ,
15+ mode : string ,
16+ callback ?: string
1317}
1418export 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 */
98160successListener . 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 ( {
0 commit comments