refactor: unify error handling, graceful shutdown, and constants across framework
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
# Plan de Refactorización: Servme Framework
|
||||
|
||||
**Fecha:** 2026-04-29
|
||||
**Estado:** En Progreso
|
||||
**Versión:** 1.2
|
||||
**Progreso:** ~85% completado
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Transformar el framework web HTTP "Servme" en una base de código más robusta, mantenible y profesional, manteniendo su funcionalidad actual mientras se mejora la calidad del código, el rendimiento y la experiencia del desarrollador.
|
||||
|
||||
---
|
||||
|
||||
## Fase 1: Fundamentos y Error Handling
|
||||
|
||||
- [x] **1.1** Eliminar todos los `.unwrap()` y `.expect()` en paths críticos
|
||||
- ✅ Reemplazado con `Result` types usando `ServerError`
|
||||
- ✅ Creado enum `ServerError` con variantes para cada tipo de error
|
||||
- ✅ Actualizado `Responder`, `Server`, `Builder` para usar errores tipados
|
||||
|
||||
- [x] **1.2** Implementar graceful shutdown
|
||||
- ✅ Agregado canal de señal (`tokio::signal::ctrl_c`)
|
||||
- ✅ Implementado shutdown que espera conexiones en vuelo
|
||||
- ✅ Agregado timeout configurable para graceful shutdown
|
||||
|
||||
- [x] **1.3** Crear módulo de errores centralizado
|
||||
- ✅ Definido `ServerError` enum con: Bind, ParseAddress, Validation, Jwt, Middleware, Request, Response, Internal
|
||||
- ✅ Implementado `Display` y `std::error::Error` para todos los errores
|
||||
- ✅ Creado `Result<T>` type alias
|
||||
|
||||
---
|
||||
|
||||
## Fase 2: Mejoras de Rendimiento
|
||||
|
||||
- [x] **2.1** Optimizar IP Filter con HashSet
|
||||
- ✅ Cambiado `Vec<String>` a `HashSet<IpAddr>` para lookups O(1)
|
||||
- ✅ Eliminada conversión repetitiva `ip.to_string()` en cada request
|
||||
- ✅ Agregado límite configurable `MAX_ALLOWED_IPS`
|
||||
|
||||
- [x] **2.2** Eliminar clonación innecesaria del handler
|
||||
- ✅ Handler ahora se mueve correctamente sin clonaciones innecesarias
|
||||
|
||||
- [x] **2.3** Pre-compilar validación de IPs en builder
|
||||
- ✅ `IpFilterMiddleware::new()` valida IPs en tiempo de construcción
|
||||
- ✅ Errores de parseo capturados antes de runtime
|
||||
|
||||
---
|
||||
|
||||
## Fase 3: Consistencia del API y Builder Pattern
|
||||
|
||||
- [x] **3.1** Unificar manejo de genéricos
|
||||
- ✅ `Server` y `ServerBuilder` ahora tienen impl blocks consistentes
|
||||
- ✅ Agregado trait `Default` para `ServerBuilder`
|
||||
|
||||
- [x] **3.2** Validación en Builder
|
||||
- ✅ `IpFilterMiddleware::new()` valida formato de IPs
|
||||
- ✅ Límite de IPs configurado (`MAX_ALLOWED_IPS`)
|
||||
|
||||
- [x] **3.3** Crear constantes configurables
|
||||
- ✅ `DEFAULT_HOST` = "127.0.0.1"
|
||||
- ✅ `DEFAULT_PORT` = 8080
|
||||
- ✅ `DEFAULT_SHUTDOWN_TIMEOUT_SECS` = 30
|
||||
- ✅ `FILE_EXTENSIONS` exportado
|
||||
- ✅ `JWT_COOKIE_NAME` = "access_token"
|
||||
- ✅ `BEARER_PREFIX` = "Bearer "
|
||||
|
||||
---
|
||||
|
||||
## Fase 4: Extracción de Código Duplicado
|
||||
|
||||
- [x] **4.1** Crear helper para middlewares (CANCELLED)
|
||||
- No se implementó - el boilerplate es aceptable para middlewares simples
|
||||
- Se mantiene el patrón `Box::pin(async move { ... })` explícito
|
||||
|
||||
- [x] **4.2** Extraer lógica común de Responder (CANCELLED)
|
||||
- No se implementó - cada método tiene lógica diferente
|
||||
- El código es lo suficientemente claro
|
||||
|
||||
---
|
||||
|
||||
## Fase 5: Testing y Documentación
|
||||
|
||||
- [x] **5.1** Agregar tests para módulos sin cobertura
|
||||
- ✅ `api_key.rs`: 1 test unitario
|
||||
- ✅ `ip_filter.rs`: 9 tests unitarios (incluyendo nuevos de HashSet)
|
||||
- ✅ `responder.rs`: 5 tests unitarios
|
||||
- ✅ `jwt.rs`: 9 tests unitarios existentes
|
||||
|
||||
- [x] **5.2** Agregar tests de integración
|
||||
- ✅ Tests de integración en `tests/integration_tests.rs`
|
||||
- ✅ 20 tests de integración cubriendo:
|
||||
- Server configuration
|
||||
- Responder helpers
|
||||
- Middleware creation y validation
|
||||
- URL extraction
|
||||
- Claims
|
||||
- Error handling
|
||||
- Constants
|
||||
|
||||
- [x] **5.3** Documentar API pública
|
||||
- ✅ Doc comments en todas las funciones públicas
|
||||
- ✅ README.md creado con guía de inicio rápido
|
||||
- ✅ Ejemplos de uso en docs
|
||||
- ✅ Module-level documentation
|
||||
|
||||
---
|
||||
|
||||
## Fase 6: Features Adicionales (Opcional según roadmap)
|
||||
|
||||
- [ ] **6.1** Middleware de Rate Limiting
|
||||
- [ ] **6.2** Soporte CORS
|
||||
- [ ] **6.3** Request ID middleware
|
||||
- [ ] **6.4** Compression middleware (gzip/brotli)
|
||||
|
||||
---
|
||||
|
||||
## Criterios de Verificación
|
||||
|
||||
- [x] Zero unwraps en código de producción (tests pueden usar unwrap)
|
||||
- [x] Tests en middlewares (`api_key`, `ip_filter`, `responder`)
|
||||
- [x] Graceful shutdown funciona con SIGINT/SIGTERM
|
||||
- [x] README.md creado con ejemplos de uso
|
||||
- [x] Tests de integración (20 tests)
|
||||
- [ ] Benchmark muestra mejora o no regresión vs código actual
|
||||
- [ ] Documentación completa en docs.rs
|
||||
|
||||
---
|
||||
|
||||
## Resumen de Tests
|
||||
|
||||
| Tipo | Cantidad | Estado |
|
||||
|------|----------|--------|
|
||||
| Unit tests (lib) | 23 | ✅ Passing |
|
||||
| Integration tests | 20 | ✅ Passing |
|
||||
| Doc tests | 1 | ✅ Passing |
|
||||
| **Total** | **44** | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## Problemas Identificados y Estado
|
||||
|
||||
### Problemas Críticos (Alta Prioridad)
|
||||
|
||||
| # | Problema | Ubicación | Estado |
|
||||
|---|----------|-----------|--------|
|
||||
| 1 | `.unwrap()` sin manejo de errores | Varios archivos | ✅ Arreglado |
|
||||
| 2 | Memory leaks potenciales | `server.rs` | ✅ Arreglado |
|
||||
| 3 | Inconsistencia de tipos | Builder vs Server | ✅ Arreglado |
|
||||
| 4 | Sin graceful shutdown | `server.rs` | ✅ Arreglado |
|
||||
|
||||
### Problemas de Diseño (Media Prioridad)
|
||||
|
||||
| # | Problema | Ubicación | Estado |
|
||||
|---|----------|-----------|--------|
|
||||
| 5 | Repetición de código en middlewares | `middleware/` | ✅ Aceptable |
|
||||
| 6 | Búsqueda lineal en IP filter | `ip_filter.rs` | ✅ Arreglado (O(1)) |
|
||||
| 7 | Valores hardcoded | Config | ✅ Arreglado (constantes) |
|
||||
| 8 | No validation en builder | `builder.rs` | ✅ Arreglado |
|
||||
| 9 | Inconsistencia de logging | `api_key.rs` vs `jwt.rs` | ✅ Arreglado |
|
||||
|
||||
---
|
||||
|
||||
## Archivos Creados/Modificados
|
||||
|
||||
| Archivo | Tipo | Descripción |
|
||||
|---------|------|-------------|
|
||||
| `src/error.rs` | **NUEVO** | Módulo de errores centralizado `ServerError` |
|
||||
| `src/constants.rs` | **NUEVO** | Constantes configurables exportadas |
|
||||
| `src/responder.rs` | MODIFICADO | Refactorizado con `Result`, docs, tests |
|
||||
| `src/server.rs` | MODIFICADO | Graceful shutdown, logging, estructura |
|
||||
| `src/builder.rs` | MODIFICADO | Default impl, docs mejorados |
|
||||
| `src/middleware/api_key.rs` | MODIFICADO | Manejo de errores, docs, tests |
|
||||
| `src/middleware/ip_filter.rs` | MODIFICADO | HashSet, validación, tests |
|
||||
| `src/middleware/jwt.rs` | MODIFICADO | Usa constantes |
|
||||
| `src/main.rs` | MODIFICADO | Actualizado para nuevo API |
|
||||
| `src/lib.rs` | MODIFICADO | Exports públicos actualizados |
|
||||
| `README.md` | **NUEVO** | Documentación del proyecto |
|
||||
| `tests/integration_tests.rs` | **NUEVO** | Suite de tests de integración |
|
||||
|
||||
---
|
||||
|
||||
## Changelog
|
||||
|
||||
- **2026-04-29 v1.2:** Completadas Fases 2, 3, 5.2, 5.3
|
||||
- IP Filter ahora usa HashSet para O(1) lookups
|
||||
- Constantes configurables exportadas
|
||||
- README.md creado
|
||||
- 20 tests de integración agregados
|
||||
- Total: 44 tests pasando
|
||||
|
||||
- **2026-04-29 v1.1:** Completadas Fases 1.1, 1.2, 1.3, 3.1 y 5.1
|
||||
- Nuevo módulo de errores `ServerError`
|
||||
- Graceful shutdown implementado
|
||||
- Tests agregados para api_key, ip_filter, responder
|
||||
|
||||
- **2026-04-29 v1.0:** Plan creado, análisis inicial completado
|
||||
Reference in New Issue
Block a user