A production-ready Go microservice for orchestrating voice pod allocation and pool management in Kubernetes.
Voice Orchestrator consists of two independent services:
- Router Service - High-performance HTTP API for pod allocation
- Pool Manager Service - Background reconciliation worker for K8s pod management
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Voice Orchestrator β
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββ€
β Router Service β Pool Manager Service β
β (HTTP API) β (Background Worker) β
β β β
β β’ Fast allocation β β’ Reconciles desired vs actual pods β
β β’ Multiple replicas β β’ Single replica only β
β β’ Reads from Redis β β’ Reads from Postgres β
β β’ Health checks β β’ Scales K8s deployments β
β β β’ Syncs Redis state β
ββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββ
β β
βββββββββββββββββββββββββββββ€
β β
ββββΌββββ ββββββββββββ βββΌβββββββββ
βRedis β βPostgres β βKubernetesβ
ββββββββ ββββββββββββ ββββββββββββ
1. Merchant Config β Postgres (merchants table with desired_pod_count)
β
2. Pool Manager reads Postgres every 10s
β
3. Pool Manager scales K8s deployments (if needed)
β
4. Pool Manager syncs Redis (merchant:{id}:pod_count)
β
5. Router reads Redis for fast pod allocation
- Go 1.25.7 (see Installation)
- Docker (optional, for containerization)
- kubectl (optional, for K8s deployment)
- Redis (for caching)
- PostgreSQL 16+ (for merchant data)
- Kubernetes cluster (for production deployment)
# Clone the repository
git clone https://github.com/MonishJuspay/voice-orchestrator.git
cd voice-orchestrator
# Run setup script
./scripts/setup-dev.sh
# Edit environment variables
cp .env.example .env
nano .env# Install Go 1.25.7 (Linux/macOS)
./scripts/install-go.sh
# Or download manually from https://go.dev/dl/
# Verify Go installation
go version # Should show: go version go1.25.7 ...
# Download dependencies
make install-deps# Start Redis
docker run -d -p 6379:6379 --name redis redis:alpine
# Start PostgreSQL
docker run -d -p 5432:5432 \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=voice_orchestrator \
--name postgres postgres:16-alpine# Terminal 1: Run Router
make run-router
# Terminal 2: Run Pool Manager
make run-pool-manager# Check Router health
curl http://localhost:8080/health
# Expected: {"status": "healthy"}make help # Show all available commands
make build # Build both services
make build-router # Build router only
make build-pool-manager # Build pool-manager only
make clean # Clean build artifactsmake test # Run tests with coverage
make test-coverage # Generate HTML coverage reportmake fmt # Format code
make vet # Run go vet
make lint # Run golangci-lint
make verify # Run all checks (fmt + vet + lint + test)# Build Docker images
make docker-build
# Push to registry (set DOCKER_REGISTRY env var)
make docker-push
# Example with custom registry
DOCKER_REGISTRY=myregistry.io/myorg make docker-build# Ensure kubectl is configured
kubectl cluster-info
# Create namespace (optional)
kubectl create namespace voice-orchestrator# Deploy both services
make k8s-deploy
# Or deploy individually
make k8s-deploy-router
make k8s-deploy-pool-manager# Edit secrets with real credentials
kubectl edit secret router-secret -n default
kubectl edit secret pool-manager-secret -n default# Check pods
kubectl get pods -l app=voice-orchestrator
# Check services
kubectl get svc router-service
# View logs
kubectl logs -l component=router -f
kubectl logs -l component=pool-manager -fmake k8s-deleteAll configuration is via environment variables. See .env.example for all options.
| Variable | Description | Default |
|---|---|---|
ENVIRONMENT |
Environment (development/production) | development |
LOG_LEVEL |
Log level (debug/info/warn/error) | info |
HTTP_PORT |
HTTP server port | 8080 |
HTTP_READ_TIMEOUT |
Read timeout | 30s |
HTTP_WRITE_TIMEOUT |
Write timeout | 30s |
REDIS_ADDR |
Redis address | localhost:6379 |
POSTGRES_HOST |
Postgres host | localhost |
K8S_NAMESPACE |
K8s namespace | default |
| Variable | Description | Default |
|---|---|---|
RECONCILE_INTERVAL |
Reconciliation interval | 10s |
REDIS_ADDR |
Redis address | localhost:6379 |
POSTGRES_HOST |
Postgres host | localhost |
K8S_NAMESPACE |
K8s namespace | default |
K8S_IN_CLUSTER |
Running in K8s cluster | false |
GET /healthResponse:
{
"status": "healthy"
}GET /readyResponse:
{
"status": "ready",
"redis": "ok",
"postgres": "ok",
"kubernetes": "ok"
}POST /api/v1/allocate
Content-Type: application/json
{
"merchant_id": "merchant-123",
"pod_count": 5
}Response:
{
"merchant_id": "merchant-123",
"allocated_pods": [
{
"pod_id": "pod-1",
"ip": "10.0.1.5",
"status": "ready"
}
]
}POST /api/v1/admin/merchants- Create merchantGET /api/v1/admin/merchants/:id- Get merchantPUT /api/v1/admin/merchants/:id- Update merchantDELETE /api/v1/admin/merchants/:id- Delete merchant
voice-orchestrator/
βββ cmd/
β βββ router/ # Router entry point
β βββ pool-manager/ # Pool manager entry point
βββ internal/
β βββ app/
β β βββ router/ # HTTP handlers & server
β β βββ poolmanager/ # Reconciliation logic
β β βββ admin/ # Admin API handlers
β βββ datastore/
β β βββ redis/ # Redis client & operations
β β βββ postgres/ # Postgres client & queries
β βββ domain/ # Domain models & DTOs
β βββ k8s/ # Kubernetes client wrapper
β βββ config/ # Configuration management
βββ pkg/
β βββ logger/ # Structured logging (zap)
βββ deployments/
β βββ router/ # K8s manifests for router
β βββ pool-manager/ # K8s manifests for pool-manager
βββ docker/ # Dockerfiles
βββ scripts/ # Helper scripts
βββ migrations/ # Database migrations
βββ Makefile # Build automation
βββ go.mod # Go module definition
βββ README.md # This file
make testgo test -v ./internal/domain/...
go test -v ./internal/app/router/...make test-coverage
open coverage.html # macOS
xdg-open coverage.html # LinuxIssue: go: cannot find module
# Solution: Download dependencies
make install-depsIssue: Go version mismatch
# Solution: Install Go 1.25.7
./scripts/install-go.shIssue: Cannot connect to Redis
# Check Redis is running
docker ps | grep redis
# Start Redis if needed
docker run -d -p 6379:6379 --name redis redis:alpineIssue: Cannot connect to Postgres
# Check Postgres is running
docker ps | grep postgres
# Start Postgres if needed
docker run -d -p 5432:5432 \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=voice_orchestrator \
--name postgres postgres:16-alpineIssue: K8s client error: unable to load in-cluster configuration
# Solution: Set K8S_IN_CLUSTER=false in .env
echo "K8S_IN_CLUSTER=false" >> .envIssue: ImagePullBackOff
# Check image exists
docker images | grep voice-orchestrator
# Build and push images
make docker-build docker-pushIssue: CrashLoopBackOff
# Check logs
kubectl logs -l component=router --tail=50
# Check secrets
kubectl get secret router-secret -o yamlStructured JSON logging (production):
{
"level": "info",
"ts": "2024-01-15T10:30:45.123Z",
"caller": "router/handler.go:45",
"msg": "Request processed",
"merchant_id": "merchant-123",
"duration_ms": 15
}Console logging (development):
2024-01-15T10:30:45.123Z INFO router/handler.go:45 Request processed merchant_id=merchant-123 duration_ms=15
- Prometheus integration planned
- Metrics endpoints:
/metrics - Key metrics: request rate, latency, pod allocation success rate
-
Clone repository
git clone https://github.com/MonishJuspay/voice-orchestrator.git cd voice-orchestrator -
Setup environment
./scripts/setup-dev.sh
-
Create feature branch
git checkout -b feature/my-feature
-
Make changes and test
make verify # Run all checks -
Commit and push
git add . git commit -m "Add feature: description" git push origin feature/my-feature
-
Create pull request
- Format code:
make fmtbefore committing - Pass linting:
make lintmust pass - Write tests: Maintain >80% coverage
- Document changes: Update README if needed
Copyright Β© 2024 Juspay Technologies. All rights reserved.
- Issues: GitHub Issues
- Documentation: Wiki
- Contact: Monish P monish.p@juspay.in Harsh Tiwari
β
Project structure and boilerplate
β
Configuration management
β
Logging infrastructure
β
Docker & Kubernetes manifests
β
CI/CD pipelines
β³ Business logic implementation (in progress)
- Complete pod allocation logic
- Redis caching layer
- Postgres repository implementation
- K8s deployment scaling
- Prometheus metrics
- Admin UI
- Rate limiting
- Authentication & authorization
- Database migrations
- Grafana dashboards
Built with β€οΈ using Go 1.25.7