This commit is contained in:
73
src/api.ts
73
src/api.ts
@@ -2,15 +2,6 @@ import axios from "axios"
|
||||
import { languageToId } from "./templates"
|
||||
import { Code, Submission } from "./types"
|
||||
|
||||
// function getChromeVersion() {
|
||||
// var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)
|
||||
// return raw ? parseInt(raw[2], 10) : 0
|
||||
// }
|
||||
|
||||
// const isLowVersion = getChromeVersion() < 80
|
||||
|
||||
// const protocol = isLowVersion ? "http" : "https"
|
||||
|
||||
function encode(string?: string) {
|
||||
return btoa(String.fromCharCode(...new TextEncoder().encode(string ?? "")))
|
||||
}
|
||||
@@ -27,7 +18,71 @@ function decode(bytes?: string) {
|
||||
const judge = axios.create({ baseURL: import.meta.env.PUBLIC_JUDGE0API_URL })
|
||||
const api = axios.create({ baseURL: import.meta.env.PUBLIC_CODEAPI_URL })
|
||||
|
||||
type PythonWorkerRequest = {
|
||||
id: number
|
||||
source: string
|
||||
stdin: string
|
||||
timeoutMs: number
|
||||
}
|
||||
|
||||
type PythonWorkerResponse = {
|
||||
id: number
|
||||
status: number
|
||||
output: string
|
||||
}
|
||||
|
||||
let pythonWorker: Worker | null = null
|
||||
let pythonWorkerSeq = 0
|
||||
const pythonPending = new Map<
|
||||
number,
|
||||
{ resolve: (v: { status: number; output: string }) => void; timeout: number }
|
||||
>()
|
||||
|
||||
function getPythonWorker() {
|
||||
if (pythonWorker) return pythonWorker
|
||||
pythonWorker = new Worker(
|
||||
new URL("./workers/pythonSkulpt.worker.ts", import.meta.url),
|
||||
{ type: "module" },
|
||||
)
|
||||
pythonWorker.onmessage = (event: MessageEvent<PythonWorkerResponse>) => {
|
||||
const { id, status, output } = event.data ?? ({} as any)
|
||||
const pending = pythonPending.get(id)
|
||||
if (!pending) return
|
||||
clearTimeout(pending.timeout)
|
||||
pythonPending.delete(id)
|
||||
pending.resolve({ status, output })
|
||||
}
|
||||
return pythonWorker
|
||||
}
|
||||
|
||||
function restartPythonWorker() {
|
||||
if (pythonWorker) pythonWorker.terminate()
|
||||
pythonWorker = null
|
||||
pythonPending.clear()
|
||||
}
|
||||
|
||||
async function runPythonInWorker(source: string, stdin: string) {
|
||||
const worker = getPythonWorker()
|
||||
const id = ++pythonWorkerSeq
|
||||
const timeoutMs = 5000
|
||||
|
||||
return new Promise<{ status: number; output: string }>((resolve) => {
|
||||
const timeout = window.setTimeout(() => {
|
||||
restartPythonWorker()
|
||||
resolve({ status: 11, output: "运行超时" })
|
||||
}, timeoutMs + 250)
|
||||
|
||||
pythonPending.set(id, { resolve, timeout })
|
||||
const message: PythonWorkerRequest = { id, source, stdin, timeoutMs }
|
||||
worker.postMessage(message)
|
||||
})
|
||||
}
|
||||
|
||||
export async function submit(code: Code, input: string) {
|
||||
if (code.language === "python") {
|
||||
return runPythonInWorker(code.value, input)
|
||||
}
|
||||
|
||||
const encodedCode = encode(code.value)
|
||||
|
||||
const id = languageToId[code.language]
|
||||
|
||||
Reference in New Issue
Block a user