Skip to content

Latest commit

 

History

History
117 lines (108 loc) · 6.93 KB

File metadata and controls

117 lines (108 loc) · 6.93 KB

Changelog

Todos los cambios relevantes de la librería. El formato sigue Keep a Changelog.

[No publicado]

Revisión de robustez y experiencia de desarrollo. No hay cambios que rompan código existente: todo lo anterior sigue compilando y comportándose igual, salvo donde el comportamiento anterior era un fallo (ver Corregido).

Añadido

  • Multi-target net8.0 / net9.0 / net10.0. Antes el paquete sólo se podía instalar en net10.0, lo que dejaba fuera a la mayoría de proyectos en producción (net8.0 es LTS).
  • DocumentoEspanol, fachada estática para el caso más común: DocumentoEspanol.EsValido("12345678Z"). Sin instanciar nada, sin asignaciones y sin excepciones.
  • AddValidacionDocumentosEspanoles(), extensión de IServiceCollection que registra IValidadorDocumentos, ValidadorDocumentosUltraFast y ProcesadorLotesUltraFast como singleton. Usa TryAdd, así que respeta una implementación propia ya registrada.
  • Streaming perezoso en ambos motores: ValidarStream(IEnumerable<string?>) y ValidarStreamAsync(IAsyncEnumerable<string?>). Memoria constante independientemente del tamaño del origen; los ValidarLote* materializan el origen entero y no sirven para ficheros que no caben en RAM.
  • Atajos booleanos en el motor ultra: EsDniValido, EsNieValido, EsNifValido, EsCifValido, EsDocumentoValido.
  • ValidarLoteCompatAsync y sobrecarga de ValidarLote para cualquier IEnumerable<string?>.
  • UtilesValidacion.TryNormalizar(ReadOnlySpan<char>, Span<char>, out int): normalización contra un buffer del llamante, cero asignaciones.
  • ResultadoValidacionUltra.Mensaje y ProcesadorLotesUltraFast.DescribirError(int): mensaje legible a partir del código de error, sin construir nada por documento.
  • IReglaValidacion<T>.Cumple(T): comprobación booleana sin construir el mensaje de error. Implementación por defecto incluida, las reglas propias no necesitan cambios.
  • ValidadorDocumentos.Instancia y ProcesadorLotesUltraFast.Instancia para uso sin contenedor de DI.
  • CancellationToken en los lotes del motor ultra (ValidarLote, ValidarLoteCompat).
  • SourceLink, símbolos (.snupkg) y build determinista en el paquete: se puede depurar con F11 dentro de la librería.
  • Marcado como IsAotCompatible e IsTrimmable.
  • 71 tests nuevos de robustez y DX (737 en total), ejecutados en net8.0 y net10.0.

Corregido

  • El motor ultra aceptaba CIFs con letra de entidad inexistente. ValidadorDocumentosUltraFast.ValidarCif("I00000000") devolvía válido (también O, T, y cualquier otra letra fuera de ABCDEFGHJNPQRSUVW), mientras que la API clásica los rechazaba. La regla nunca comprobaba el primer carácter: el código de error 403 existía pero no se emitía nunca. Ambos motores dan ahora el mismo veredicto sobre cualquier entrada.
  • Los lotes asíncronos perdían el orden de entrada. ValidarLote*Async acumulaba en un ConcurrentBag, así que ResultadosIndividuales[i] no correspondía al documento i y el resultado no coincidía con el de la versión síncrona. Ahora se escribe en un array indexado por partición.
  • ProcesarStreamAsync dejaba colgado al consumidor. Si un worker fallaba o se cancelaba la operación, el canal de salida no se completaba nunca y el await foreach del consumidor esperaba de forma indefinida. Ahora se completa siempre (con la excepción, si la hubo) en un finally.
  • La cancelación no cancelaba nada. ValidarLoteAsync sólo pasaba el token a Task.Run, lo que impide empezar pero no parar: un lote de millones de documentos seguía ocupando todos los núcleos hasta terminar. Ahora el token se comprueba durante el proceso, en ambos motores.
  • Fuga de memoria en el procesador de lotes. Dos ConcurrentDictionary estáticos cacheaban resultados sin límite ni expiración. Con documentos distintos —el caso real de un padrón o un censo— crecían sin tope: un millón de documentos únicos dejaba ~100 MB retenidos permanentemente, y las tandas sucesivas acababan en OutOfMemoryException. Se han eliminado; recalcular cuesta nanosegundos.
  • Normalizar reservaba memoria proporcional a la entrada. Una entrada anómala de 40 MB reservaba un char[] de 80 MB en el LOH. Ahora la memoria usada no depende del tamaño de la entrada.
  • ErrorValidacion.CodigoErrorString construía una excepción en cada lectura, sólo para leerle una propiedad (~136 bytes por lectura). Ahora resuelve con una tabla.
  • Resumen y los porcentajes dependían de la cultura del proceso: el mismo lote daba 66,67% en un servidor es-ES y 66.67% en uno en-US. Ahora se formatean con InvariantCulture.
  • ValidadorEncadenado.AcumularErrores() mutaba la instancia, de modo que pedir la versión acumulada cambiaba el modo de evaluación para el resto de consumidores. Ahora devuelve un validador nuevo con su propia copia de reglas.
  • Códigos de error desconocidos se casteaban a un valor de enum inexistente. Ahora se mapean a ReglaValidacionFallida.
  • Ejemplos del README que no compilaban: espacio de nombres incorrecto (nif_dni_nie_cif_validation), ValidarDniSpan tratado como bool y ValidarDocumento(Span) en lugar de ValidarDocumentoSpan. El ejemplo de Channel<T> mostraba además un patrón que interbloquea con canales acotados.

Cambiado

  • Los caminos booleanos ya no usan excepciones como control de flujo. Dni.Intentar, Nie.Intentar, Nif.Intentar, Cif.Intentar y todos los EsXValido validaban dentro de un try/catch: cada documento inválido lanzaba y capturaba una excepción completa (~1,3 KB y varios microsegundos). Ahora validan y sólo construyen si procede.
  • Las cadenas de reglas se construyen una sola vez. Antes cada validación creaba 5 objetos regla + una lista + LINQ. EsDniValido ha pasado de 379 ns y 856 B a ~35 ns y 0 B.
  • Las reglas del motor ultra ya no construyen texto en el camino de fallo. El detalle interpolado que generaban no lo leía nadie.
  • Los métodos de validación aceptan string? y los lotes IEnumerable<string?>?: la tolerancia a null ya existía, ahora también la declara la firma.
  • IntentarValidarX valida una sola vez (antes ejecutaba la cadena de reglas y después repetía la validación completa al construir el objeto de valor).
  • CrearValidador() sigue devolviendo una instancia nueva, extensible con .Agregar(...) sin afectar a la que usa la librería.
  • CI: timeout-minutes en los jobs y en los tests (un test colgado ya no puede retener un runner durante horas), build con -warnaserror, tests contra los runtimes de los tres TFMs y ejecución también en pull requests.
  • Corregidas las 29 advertencias de compilación (documentación XML ausente o con referencias cref sin resolver). El build está limpio con -warnaserror.