Code Relay Judge System: Under the Hood
Welcome to the Code Relay Judge System—a modern, real-time competitive programming platform designed for team-based code relay competitions! This blog will take you through what the system does, how it works, and the architectural choices that make it robust, secure, and fun.
What is Code Relay?
Code Relay is a unique competitive programming format where teams of programmers solve algorithmic problems together, but with a twist:
- Each team member gets a fixed time window to code.
- When the timer runs out, the next member continues from where the previous left off.
- The goal? Solve as many problems as possible, as a team, under pressure!
System Arch:
The system is built with modularity, security, and real-time feedback in mind. Here’s how the main components fit together:
1. Express.js Server (server.js)
- Handles HTTP requests for code submissions, status checks, and leaderboard data.
- Exposes RESTful endpoints for submitting code (as text or file), checking job status, and fetching the leaderboard.
- Manages team configurations and ensures only one submission per team is processed at a time.
2. Submission Queue (queue.js)
- Implements an in-memory queue to manage incoming code submissions.
- Ensures submissions are processed sequentially to avoid resource contention.
- Handles timeouts and updates the leaderboard with partial scores as soon as results are available.
3. Code Runner (run_code.js)
- Executes submitted code inside isolated Docker containers for maximum security.
- Supports multiple languages: Python, Java, C++, C, and JavaScript.
- Mounts code and test input files into the container, runs the code, and compares outputs against expected results.
- Returns detailed feedback for each test case (pass/fail, actual vs. expected output).
4. Database (database.js)
- Uses simple file-based storage (JSON files) for results and leaderboard data.
- Easy to inspect, backup, and reset for new competitions.
5. Team Management (team_config.js)
- Lets you configure teams, members, and manage the rotation logic.
- Handles timers for discussion and coding phases, ensuring fair play.
6. Frontend (public/)
- Clean, real-time web interface for code submission, problem browsing, and leaderboard viewing.
- Features a code editor, problem descriptions, and a live timer for team rotations.
- Uses Tailwind CSS for modern, responsive styling.
Security & Isolation
- All code runs in Docker containers: This ensures that user-submitted code cannot harm the host system.
- Each submission is run in a fresh container, with strict timeouts and resource limits.
Real-Time Experience
- Live leaderboard: Updates instantly as teams submit solutions and earn points.
- Submission feedback: Teams see which test cases passed or failed, with detailed error messages if something goes wrong.
- Automatic team rotation: The system enforces coding windows and rotates team members automatically.
Extensible Problem System
- Problems are stored in the
/problems/directory, each with its own set of test cases. - Adding a new problem is as simple as creating a new folder and dropping in your test files.
- The frontend can be updated to display new problems with rich descriptions and examples.
Tech Stack
- Backend: Node.js, Express.js, Docker, fs-extra
- Frontend: HTML, Tailwind CSS, JavaScript
- Storage: JSON files (for leaderboard, results, team configs)
- Security: Docker-based code isolation
File Structure Overview
/submissions/ # Submitted code files
/problems/ # Problem descriptions and test cases
/db/ # Leaderboard and results data
/public/ # Frontend files (HTML, CSS, JS)
/config/ # Team and competition configuration
Why This way?
- Security: Docker ensures that even malicious code can’t escape its sandbox.
- Simplicity: File-based storage is easy to manage and inspect for small competitions.
- Extensibility: Adding new languages or problems is straightforward.
- Real-time Feedback: In-memory queue and live updates keep the competition fast-paced and engaging.