# Predictor Service A Go-based weather prediction service that downloads and processes GRIB files for wind vector data extraction. ## Features - **GRIB File Processing**: Downloads and processes GRIB weather data files - **Wind Vector Extraction**: Extracts wind vector data for given coordinates and time - **Redis Caching**: Caches extraction results for improved performance - **Distributed Locking**: Uses Redis-based distributed locks for safe concurrent downloads - **Scheduled Updates**: Automatic GRIB file updates via configurable scheduler - **REST API**: HTTP API for data extraction and service management - **Modular Architecture**: Clean separation of concerns with dependency injection ## Architecture The service follows a modular architecture with clear separation of concerns: - **Service Layer**: Business logic and orchestration - **GRIB Package**: GRIB file processing and data extraction - **Redis Package**: Caching and distributed locking - **Scheduler Package**: Job scheduling and execution - **Transport Layer**: HTTP API handling - **Jobs**: Background tasks (GRIB updates, etc.) ## Quick Start with Docker ### Prerequisites - Docker - Docker Compose ### Running the Service 1. **Clone the repository:** ```bash git clone cd predictor ``` 2. **Start the services:** ```bash # Production docker-compose up -d # Development (with volume mounts) docker-compose -f docker-compose.dev.yml up -d ``` 3. **Check service status:** ```bash docker-compose ps ``` 4. **View logs:** ```bash # All services docker-compose logs -f # Specific service docker-compose logs -f predictor docker-compose logs -f redis ``` ### Using Make Commands The project includes a Makefile for common operations: ```bash # Build and start services make up-build # View logs make logs # Stop services make down # Clean up everything make clean # Show all available commands make help ``` ## Configuration The service is configured via environment variables with the prefix `GSN_PREDICTOR_`: ### GRIB Configuration - `GSN_PREDICTOR_GRIB_DIR`: Directory for GRIB files (default: `/tmp/grib`) - `GSN_PREDICTOR_GRIB_TTL`: GRIB file TTL (default: `24h`) - `GSN_PREDICTOR_GRIB_CACHE_TTL`: Cache TTL (default: `1h`) - `GSN_PREDICTOR_GRIB_PARALLEL`: Parallel download workers (default: `4`) - `GSN_PREDICTOR_GRIB_TIMEOUT`: Download timeout (default: `30s`) - `GSN_PREDICTOR_GRIB_DATASET_URL`: GRIB data source URL ### Redis Configuration - `GSN_PREDICTOR_REDIS_HOST`: Redis host (default: `localhost`) - `GSN_PREDICTOR_REDIS_PORT`: Redis port (default: `6379`) - `GSN_PREDICTOR_REDIS_PASSWORD`: Redis password (default: empty) - `GSN_PREDICTOR_REDIS_DB`: Redis database (default: `0`) ### Scheduler Configuration - `GSN_PREDICTOR_SCHEDULER_ENABLED`: Enable scheduler (default: `true`) ### GRIB Updater Job Configuration - `GSN_PREDICTOR_GRIB_UPDATER_INTERVAL`: Update interval (default: `6h`) - `GSN_PREDICTOR_GRIB_UPDATER_TIMEOUT`: Update timeout (default: `45m`) ### REST Transport Configuration - `GSN_PREDICTOR_REST_HOST`: HTTP host (default: `0.0.0.0`) - `GSN_PREDICTOR_REST_PORT`: HTTP port (default: `8080`) - `GSN_PREDICTOR_REST_READ_TIMEOUT`: Read timeout (default: `30s`) - `GSN_PREDICTOR_REST_WRITE_TIMEOUT`: Write timeout (default: `30s`) - `GSN_PREDICTOR_REST_IDLE_TIMEOUT`: Idle timeout (default: `60s`) ## API Endpoints The service exposes a REST API for wind data extraction: - `GET /health` - Health check endpoint - `POST /predict` - Extract wind data for given coordinates and time ### Example API Usage ```bash # Health check curl http://localhost:8080/health # Extract wind data curl -X POST http://localhost:8080/predict \ -H "Content-Type: application/json" \ -d '{ "latitude": 40.7128, "longitude": -74.0060, "altitude": 100, "timestamp": "2024-01-15T12:00:00Z" }' ``` ## Development ### Local Development 1. **Install dependencies:** ```bash go mod download ``` 2. **Start Redis:** ```bash docker run -d --name redis -p 6379:6379 redis:7.2-alpine ``` 3. **Set environment variables:** ```bash cd cmd/api source .env ``` 4. **Run the service:** ```bash go run . ``` ### Building Locally ```bash # Build the binary make build-local # Run tests make test # Format code make fmt # Lint code make lint ``` ### Docker Development For development with hot reloading: ```bash # Start development environment docker-compose -f docker-compose.dev.yml up -d # View logs docker-compose -f docker-compose.dev.yml logs -f predictor ``` ## Docker Best Practices The Dockerfile follows Go best practices: - **Multi-stage build**: Separate builder and runtime stages - **Non-root user**: Runs as non-root user for security - **Minimal runtime**: Uses Alpine Linux for smaller image size - **Health checks**: Built-in health monitoring - **Optimized layers**: Efficient layer caching - **Security**: No unnecessary packages or permissions ## Monitoring and Health Checks The service includes built-in health checks: - **Application health**: HTTP endpoint at `/health` - **Docker health**: Container health check with wget - **Redis health**: Redis ping health check - **Service dependencies**: Proper startup order with health checks ## Troubleshooting ### Common Issues 1. **Redis connection refused:** - Ensure Redis is running: `docker-compose ps` - Check Redis logs: `docker-compose logs redis` - Verify network connectivity 2. **GRIB download failures:** - Check internet connectivity - Verify GRIB data source URL - Check disk space in `/tmp/grib` 3. **Service not starting:** - Check logs: `docker-compose logs predictor` - Verify environment variables - Check port conflicts ### Debug Commands ```bash # Execute shell in container docker-compose exec predictor sh # Check Redis connectivity docker-compose exec redis redis-cli ping # View container resources docker stats # Check network connectivity docker-compose exec predictor wget -O- http://redis:6379 ``` ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Add tests 5. Run tests and linting 6. Submit a pull request ## License [Add your license information here]