diff --git a/app/Http/Controllers/InterviewController.php b/app/Http/Controllers/InterviewController.php index 45ca34d..e7eb740 100644 --- a/app/Http/Controllers/InterviewController.php +++ b/app/Http/Controllers/InterviewController.php @@ -155,69 +155,71 @@ public function executeCode(Request $request) $code = $request->code; $output = ''; - // 1. Instant Local CLI Process Execution (0.02s response for Node.js, Python, PHP) - try { - if (in_array($langKey, ['javascript', 'js'])) { - $process = new \Symfony\Component\Process\Process(['node', '-e', $code]); - $process->setTimeout(4); - $process->run(); - $out = $process->getOutput() ?: $process->getErrorOutput(); - $output = trim($out) ?: 'JavaScript executed successfully (no stdout).'; - } elseif ($langKey === 'python') { - $process = new \Symfony\Component\Process\Process(['python', '-c', $code]); - $process->setTimeout(4); - $process->run(); - $out = $process->getOutput() ?: $process->getErrorOutput(); - $output = trim($out) ?: 'Python executed successfully (no stdout).'; - } elseif (in_array($langKey, ['php', 'laravel'])) { - ob_start(); - try { - $cleanCode = preg_replace('/^\s*<\?php\s*/i', '', $code); - eval($cleanCode); - $out = ob_get_clean(); - $output = trim($out) ?: 'PHP code executed successfully.'; - } catch (\Throwable $e) { - ob_end_clean(); - $output = 'PHP Evaluation Error: ' . $e->getMessage(); + // 1. Ultra-Fast Piston Code Execution API (sub-second for C, C++, Java, JS, Python, PHP, Go, Rust) + $pistonLangMap = [ + 'python' => 'python', + 'py' => 'python', + 'javascript' => 'javascript', + 'js' => 'javascript', + 'c' => 'c', + 'cpp' => 'c++', + 'c++' => 'c++', + 'java' => 'java', + 'php' => 'php', + 'laravel' => 'php', + 'go' => 'go', + 'rust' => 'rust', + ]; + + if (isset($pistonLangMap[$langKey])) { + try { + $pistonLang = $pistonLangMap[$langKey]; + $response = Http::timeout(4)->post('https://emkc.org/api/v2/piston/execute', [ + 'language' => $pistonLang, + 'version' => '*', + 'files' => [ + ['content' => $code] + ] + ]); + + if ($response->successful()) { + $resData = $response->json(); + $output = $resData['run']['output'] ?? ($resData['run']['stdout'] ?? ''); + if (empty($output) && !empty($resData['run']['stderr'])) { + $output = $resData['run']['stderr']; + } } - } - } catch (\Exception $e) { - // Local execution exception; fall through to Judge0 API + } catch (\Exception $e) {} } - // 2. Remote Compiler API (Judge0 CE) for C, C++, Java or non-local runtimes + // 2. Instant Local Process Runner Fallback if (empty($output)) { - $judge0Map = [ - 'python' => 71, - 'c' => 50, - 'cpp' => 54, - 'c++' => 54, - 'java' => 62, - 'php' => 68, - 'laravel' => 68, - 'javascript' => 63, - 'js' => 63, - ]; - - if (isset($judge0Map[$langKey])) { - try { - $response = Http::timeout(5)->post('https://ce.judge0.com/submissions?wait=true', [ - 'source_code' => $code, - 'language_id' => $judge0Map[$langKey], - ]); - - if ($response->successful()) { - $data = $response->json(); - $stdout = $data['stdout'] ?? ''; - $stderr = $data['stderr'] ?? ''; - $compile = $data['compile_output'] ?? ''; - $msg = $data['message'] ?? ''; - - $outputParts = array_filter([$stdout, $stderr, $compile, $msg]); - $output = trim(implode("\n", $outputParts)); + try { + if (in_array($langKey, ['javascript', 'js'])) { + $process = new \Symfony\Component\Process\Process(['node', '-e', $code]); + $process->setTimeout(3); + $process->run(); + $out = $process->getOutput() ?: $process->getErrorOutput(); + $output = trim($out) ?: 'JavaScript executed successfully (no stdout).'; + } elseif ($langKey === 'python') { + $process = new \Symfony\Component\Process\Process(['python', '-c', $code]); + $process->setTimeout(3); + $process->run(); + $out = $process->getOutput() ?: $process->getErrorOutput(); + $output = trim($out) ?: 'Python executed successfully (no stdout).'; + } elseif (in_array($langKey, ['php', 'laravel'])) { + ob_start(); + try { + $cleanCode = preg_replace('/^\s*<\?php\s*/i', '', $code); + eval($cleanCode); + $out = ob_get_clean(); + $output = trim($out) ?: 'PHP code executed successfully.'; + } catch (\Throwable $e) { + ob_end_clean(); + $output = 'PHP Evaluation Error: ' . $e->getMessage(); } - } catch (\Exception $e) {} - } + } + } catch (\Exception $e) {} } if (empty($output)) { diff --git a/resources/views/interview/candidate_room.blade.php b/resources/views/interview/candidate_room.blade.php index edb8b51..3b552b4 100644 --- a/resources/views/interview/candidate_room.blade.php +++ b/resources/views/interview/candidate_room.blade.php @@ -368,7 +368,7 @@
No messages yet. Send a message below.
- + @@ -460,6 +460,11 @@ // Real-Time Instant BroadcastChannel + Backend Code Sync const liveSyncChannel = new BroadcastChannel('live_sync_' + '{{ $interview->id }}'); + liveSyncChannel.onmessage = function(event) { + if (event.data && event.data.type === 'chat_message' && typeof pollCandidateChat === 'function') { + pollCandidateChat(); + } + }; let codeSyncTimeout = null; editor.onDidChangeModelContent(function () { const code = editor.getValue(); @@ -1824,6 +1829,10 @@ function sendCandidateMessage() { if (!msg) return; input.value = ''; + if (typeof liveSyncChannel !== 'undefined' && liveSyncChannel) { + liveSyncChannel.postMessage({ type: 'chat_message', message: msg, sender: 'candidate' }); + } + fetch(`{{ route('interview.candidate.send-message', $interview->id) }}`, { method: 'POST', headers: { @@ -1834,9 +1843,7 @@ function sendCandidateMessage() { }) .then(r => r.json()) .then(res => { - if (res.success) { - pollCandidateChat(); - } + pollCandidateChat(); }); } diff --git a/resources/views/interview/index.blade.php b/resources/views/interview/index.blade.php index c8830fe..9bf09db 100644 --- a/resources/views/interview/index.blade.php +++ b/resources/views/interview/index.blade.php @@ -749,7 +749,7 @@
No chat history. Send a message below.
- + @@ -1270,6 +1270,8 @@ function subscribeLiveSync(interviewId) { if (drawingImg) drawingImg.style.display = 'none'; if (noDrawing) noDrawing.style.display = 'block'; } + } else if (data.type === 'chat_message') { + pollReviewData(); } }; } @@ -2245,6 +2247,10 @@ function sendSilentWarning() { if (!msg || !currentInterviewId) return; input.value = ''; + if (typeof liveSyncChannel !== 'undefined' && liveSyncChannel) { + liveSyncChannel.postMessage({ type: 'chat_message', message: msg, sender: 'interviewer' }); + } + fetch(`{{ route('interview.warning', ':id') }}`.replace(':id', currentInterviewId), { method: 'POST', headers: { @@ -2255,9 +2261,7 @@ function sendSilentWarning() { }) .then(r => r.json()) .then(res => { - if (res.success) { - pollReviewData(); - } + pollReviewData(); }); }