A real-time code execution pipeline built with Amazon SQS and Java.
POST /execute → api-service → SQS (code-submissions)
↓
worker-service → Docker (python-runner)
↓
SQS (execution-results) → api-service → PostgreSQL
GET /result/{id} ← api-service ← PostgreSQL
- Java 17, Maven, Docker
- Node.js 18+ (frontend)
- AWS CLI (for local queue setup or AWS queue creation)
Local PostgreSQL (default):
docker compose up -d postgres python-runner
./scripts/setup-sqs-local.shManaged PostgreSQL (e.g. Neon): skip the postgres container and set DATABASE_URL before starting api-service (see Database below).
Copy the export lines printed by the script into your shell.
mvn clean install -DskipTestsUse the export lines from step 1 in the same terminal (SQS credentials + queue URLs), then:
export GEMINI_API_KEY="your-google-ai-studio-key" # optional, for AI suggestions
mvn -pl api-service spring-boot:runOr build and run in one step: mvn -pl api-service -am spring-boot:run
mvn -pl worker-service spring-boot:runcd frontend
npm install
npm run devOpen http://localhost:3000.
In the AWS SQS console (same region as your app, e.g. us-east-1):
- Create queue → name:
code-submissions→ Standard queue → Create - Create queue → name:
execution-results→ Standard queue → Create
Copy each Queue URL (looks like https://sqs.us-east-1.amazonaws.com/123456789012/code-submissions).
Create an IAM user or role for api-service and worker-service with:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sqs:SendMessage",
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:GetQueueAttributes"
],
"Resource": [
"arn:aws:sqs:REGION:ACCOUNT_ID:code-submissions",
"arn:aws:sqs:REGION:ACCOUNT_ID:execution-results"
]
}
]
}Attach to an EC2 instance role, ECS task role, or use access keys on a VPS.
On the server running both Java services:
export AWS_REGION=us-east-1
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export SQS_SUBMISSION_QUEUE_URL=https://sqs.us-east-1.amazonaws.com/ACCOUNT/code-submissions
export SQS_RESULT_QUEUE_URL=https://sqs.us-east-1.amazonaws.com/ACCOUNT/execution-results
# Do NOT set AWS_ENDPOINT_URL in production (real AWS only)
unset AWS_ENDPOINT_URL
export GEMINI_API_KEY=...
export POSTGRES_PASSWORD=... # if you changed the defaultOptional tuning:
| Variable | Default | Purpose |
|---|---|---|
SQS_POLL_INTERVAL_MS |
1000 |
Delay between poll cycles |
SQS_MAX_MESSAGES |
10 |
Messages per receive call |
SQS_VISIBILITY_TIMEOUT_SECONDS |
60 |
Hide message while processing |
Run api-service, worker-service, and frontend. Use a managed Postgres URL via DATABASE_URL, or start local Postgres with docker compose up -d postgres python-runner.
For production: frontend on Vercel, api + worker on EC2 behind nginx at api.codestream.npsolver.io — see deploy/EC2-DEPLOY.md and deploy/env.vercel.example.
api-service connects to PostgreSQL using either a DATABASE_URL (managed/hosted DB) or local Docker defaults.
Set a standard Postgres connection URL. When DATABASE_URL is set, it overrides the local Docker settings:
export DATABASE_URL="postgresql://USER:PASSWORD@HOST/DBNAME?sslmode=require"
mvn -pl api-service spring-boot:runExample (Neon pooler):
export DATABASE_URL="postgresql://neondb_owner:YOUR_PASSWORD@ep-example-pooler.us-east-1.aws.neon.tech/neondb?sslmode=require"Flyway runs migrations on startup. For managed databases (Neon), the app automatically baselines when needed and skips V1 if execution_results already exists.
When DATABASE_URL is not set, api-service uses:
| Variable | Default |
|---|---|
POSTGRES_HOST |
localhost |
POSTGRES_PORT |
5432 |
POSTGRES_DB |
codestream |
POSTGRES_USER |
codestream |
POSTGRES_PASSWORD |
codestream |
Start the container:
docker compose up -d postgresOptional JDBC query string for local overrides: POSTGRES_JDBC_PARAMS (e.g. ?sslmode=disable).
| Variable | Service | Purpose |
|---|---|---|
SQS_SUBMISSION_QUEUE_URL |
api, worker | Jobs from API to worker |
SQS_RESULT_QUEUE_URL |
api, worker | Results from worker to API |
AWS_REGION |
api, worker | AWS region |
AWS_ENDPOINT_URL |
api, worker | LocalStack only (http://localhost:4566) |
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY |
api, worker | AWS credentials |
GEMINI_API_KEY |
api | AI fix suggestions |
DATABASE_URL |
api | Managed Postgres URL (overrides local Docker DB) |
POSTGRES_HOST / POSTGRES_PORT / POSTGRES_DB |
api | Local Docker Postgres (when DATABASE_URL unset) |
POSTGRES_USER / POSTGRES_PASSWORD |
api | Local Docker Postgres credentials |
CORS_ALLOWED_ORIGIN_PATTERNS |
api | Comma-separated CORS origins (production domain) |
EXECUTION_DOCKER_* |
worker | Docker sandbox limits and image name |
RESULT_RETENTION_DAYS |
api | Postgres result retention |
Next.js app in frontend/. It posts Python code to the api-service, polls for results, and shows stdout or errors.
Local dev: uses Next.js rewrites (/api/* → http://localhost:8082). Override with API_SERVICE_URL.
Production (Vercel): set API_SERVICE_URL=https://api.codestream.npsolver.io. Browser calls /api/*; Vercel rewrites proxy to the API. Redeploy after changing. See deploy/env.vercel.example.
When Python execution fails, the UI asks Gemini for a fix and shows a summary, explanation, and suggested code.
- Open Google AI Studio and sign in.
- Go to Get API key → Create API key.
- Set
GEMINI_API_KEYwhen starting api-service.
Optional: GEMINI_MODEL=gemini-2.5-flash (default).
- Editor code is saved in the browser (
localStorage) and restored after refresh. - Execution results in PostgreSQL are deleted automatically after 1 day (configurable via
RESULT_RETENTION_DAYS).