mirror of
https://github.com/HeyPuter/puter.git
synced 2026-01-07 05:30:31 -06:00
dev: add judge0 exec and polling
This commit is contained in:
@@ -12,6 +12,17 @@ class Judge0Client {
|
||||
return await this.get_('/about');
|
||||
}
|
||||
|
||||
async create_submission ({ lang_id, code }) {
|
||||
return await this.post_('/submissions', {
|
||||
language_id: lang_id,
|
||||
source_code: code,
|
||||
});
|
||||
}
|
||||
|
||||
async get_submission (id) {
|
||||
return await this.get_(`/submissions/${id}`);
|
||||
}
|
||||
|
||||
async get_ (path) {
|
||||
if ( ! path.startsWith('/') ) {
|
||||
path = `/${path}`;
|
||||
@@ -27,6 +38,24 @@ class Judge0Client {
|
||||
|
||||
return resp.data;
|
||||
}
|
||||
|
||||
async post_ (path, data) {
|
||||
if ( ! path.startsWith('/') ) {
|
||||
path = `/${path}`;
|
||||
}
|
||||
|
||||
const resp = await axios.request({
|
||||
method: 'POST',
|
||||
url: `${this.baseURL}${path}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data,
|
||||
});
|
||||
|
||||
return resp.data;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { Judge0Client };
|
||||
@@ -1,33 +1,90 @@
|
||||
const putility = require("@heyputer/putility");
|
||||
const BaseService = require("../../services/BaseService");
|
||||
const { Judge0Client } = require("./Judge0Client");
|
||||
const { Context } = require("../../util/context");
|
||||
|
||||
class Judge0Service extends BaseService {
|
||||
_construct () {
|
||||
this.about_ = {};
|
||||
}
|
||||
|
||||
async _init () {
|
||||
this.languages = require('./languages/languages');
|
||||
this.client = new Judge0Client({
|
||||
token: this.config.token,
|
||||
});
|
||||
|
||||
// this.submissions_ = {};
|
||||
}
|
||||
|
||||
static IMPLEMENTS = {
|
||||
['puter-exec']: {
|
||||
async about () {
|
||||
return this.about ?? (this.about = await this.client.about());
|
||||
},
|
||||
async supported () {
|
||||
return require('./languages/languages');
|
||||
},
|
||||
async exec ({ runtime, code }) {
|
||||
return await this.exec_(runtime, code);
|
||||
return await this.exec_({ runtime, code });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async _init () {
|
||||
this.client = new Judge0Client({
|
||||
token: this.config.token,
|
||||
});
|
||||
}
|
||||
async exec_ ({ runtime, code }) {
|
||||
const lang_id = (() => {
|
||||
if ( runtime.startsWith('j0-') ) {
|
||||
return runtime.slice(3);
|
||||
}
|
||||
let lang = this.languages.find((lang) => lang.language === runtime);
|
||||
if ( lang ) {
|
||||
return lang.judge0_id;
|
||||
}
|
||||
})();
|
||||
|
||||
async exec_ (runtime, code) {
|
||||
//
|
||||
if ( !lang_id ) {
|
||||
throw new Error(`Language or runtime not found: ${runtime}`);
|
||||
}
|
||||
|
||||
const result = await this.client.create_submission({
|
||||
lang_id,
|
||||
code,
|
||||
});
|
||||
|
||||
const submission_done = new putility.libs.promise.TeePromise();
|
||||
(async () => {
|
||||
// Need to poll the submission until it's done
|
||||
let poll = setInterval(async () => {
|
||||
const submission = await this.client.get_submission(result.token);
|
||||
if ( submission.status.id >= 3 ) {
|
||||
clearInterval(poll);
|
||||
// this.submissions_[result.id] = submission;
|
||||
submission_done.resolve(submission);
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for the submission to be done
|
||||
const submission = await submission_done;
|
||||
|
||||
this.log.noticeme('Submission done', submission);
|
||||
|
||||
// Send event
|
||||
const svc_event = this.services.get('event');
|
||||
svc_event.emit('puter-exec.submission.done', {
|
||||
id: submission.token,
|
||||
actor: Context.get('actor'),
|
||||
output: submission.stdout,
|
||||
summary: submission.message,
|
||||
measures: {
|
||||
time: submission.time,
|
||||
memory: submission.memory,
|
||||
},
|
||||
aux_outputs: {
|
||||
compile: submission.compile_output,
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,11 @@ class PuterExecModule extends AdvancedBase {
|
||||
|
||||
const ExecInterfaceService = require('./ExecInterfaceService');
|
||||
services.registerService('__exec-interfaces', ExecInterfaceService);
|
||||
|
||||
if ( !! config?.services?.['judge0'] ) {
|
||||
const Judge0Service = require('./Judge0Service');
|
||||
services.registerService('judge0', Judge0Service);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user