maheshnaidu/code-execution-7
0
1const express = require('express');2const fs = require('fs');3const path = require('path');4const { exec } = require('child_process');5const uuid = require('uuid');6 7const app = express();8app.use(express.json());9 10const PORT = process.env.PORT || 7860;11 12// Simple Concurrency Queue to prevent CPU thrashing13const MAX_CONCURRENT = 4; // Optimal for 2 vCPU Hugging Face Space14let activeRuns = 0;15const runQueue = [];16 17function processQueue() {18 if (runQueue.length === 0 || activeRuns >= MAX_CONCURRENT) {19 return;20 }21 22 const { task, resolve } = runQueue.shift();23 activeRuns++;24 25 task()26 .then((result) => {27 activeRuns--;28 resolve(result);29 processQueue();30 })31 .catch((err) => {32 activeRuns--;33 resolve({ stdout: '', stderr: err.message, code: 1, signal: null });34 processQueue();35 });36}37 38function queueRun(task) {39 return new Promise((resolve) => {40 runQueue.push({ task, resolve });41 processQueue();42 });43}44 45// Helper to run a command with timeout and stdin46function runCommand(command, stdin = '', timeoutMs = 25000) {47 return queueRun(() => {48 return new Promise((resolve) => {49 const child = exec(command, { timeout: timeoutMs }, (error, stdout, stderr) => {50 resolve({51 stdout: stdout || '',52 stderr: stderr || '',53 code: error ? (error.code || 1) : 0,54 signal: error ? (error.signal || null) : null55 });56 });57 58 if (stdin && child.stdin) {59 child.stdin.write(stdin);60 child.stdin.end();61 }62 });63 });64}65 66app.post('/api/v2/execute', async (req, res) => {67 const { language, files, stdin } = req.body;68 69 if (!files || files.length === 0) {70 return res.status(400).json({ error: 'No files provided' });71 }72 73 const code = files[0].content;74 const runId = uuid.v4();75 const tempDir = path.join('/tmp', runId);76 77 try {78 fs.mkdirSync(tempDir, { recursive: true });79 80 let compileCmd = '';81 let runCmd = '';82 let filePath = '';83 84 const cleanLang = (language || '').toLowerCase();85 86 if (cleanLang === 'java') {87 const classMatch = code.match(/class\s+([A-Za-z0-9_]+)/);88 const className = classMatch ? classMatch[1] : 'Main';89 filePath = path.join(tempDir, `${className}.java`);90 fs.writeFileSync(filePath, code);91 92 compileCmd = `javac ${filePath}`;93 runCmd = `java -cp ${tempDir} ${className}`;94 } else if (cleanLang === 'cpp' || cleanLang === 'c++') {95 filePath = path.join(tempDir, 'prog.cpp');96 fs.writeFileSync(filePath, code);97 const binaryPath = path.join(tempDir, 'prog.out');98 99 compileCmd = `g++ -O3 ${filePath} -o ${binaryPath}`;100 runCmd = binaryPath;101 } else if (cleanLang === 'python' || cleanLang === 'python3') {102 filePath = path.join(tempDir, 'prog.py');103 fs.writeFileSync(filePath, code);104 runCmd = `python3 ${filePath}`;105 } else if (cleanLang === 'javascript' || cleanLang === 'js') {106 filePath = path.join(tempDir, 'prog.js');107 fs.writeFileSync(filePath, code);108 runCmd = `node ${filePath}`;109 } else {110 return res.status(400).json({ error: `Language ${language} not supported.` });111 }112 113 if (compileCmd) {114 const compileResult = await runCommand(compileCmd, '', 25000);115 if (compileResult.code !== 0) {116 return res.json({117 run: {118 stdout: '',119 stderr: compileResult.stderr || 'Compilation failed',120 output: compileResult.stderr || 'Compilation failed',121 code: compileResult.code,122 signal: compileResult.signal123 }124 });125 }126 }127 128 const runResult = await runCommand(runCmd, stdin, 25000);129 const output = runResult.stdout + (runResult.stderr ? '\n' + runResult.stderr : '');130 131 res.json({132 run: {133 stdout: runResult.stdout,134 stderr: runResult.stderr,135 output: output,136 code: runResult.code,137 signal: runResult.signal138 }139 });140 141 } catch (err) {142 res.status(500).json({ error: err.message });143 } finally {144 try {145 fs.rmSync(tempDir, { recursive: true, force: true });146 } catch (cleanupErr) {}147 }148});149 150app.get('/', (req, res) => {151 res.send('Aisprx Code Execution API is running successfully.');152});153 154app.listen(PORT, () => {155 console.log(`Server is running on port ${PORT}`);156});