From d091d91f89906800988c588ea367c51a08a50b64 Mon Sep 17 00:00:00 2001 From: dmolinari Date: Mon, 8 Sep 2025 14:19:16 -0300 Subject: [PATCH] Try TimeOut Telegramas --- .../LowPriorityDataWorker.cs | 94 ++++++++++--------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs b/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs index d5e52a8..4d8be21 100644 --- a/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs +++ b/Elecciones-Web/src/Elecciones.Worker/LowPriorityDataWorker.cs @@ -727,14 +727,11 @@ public class LowPriorityDataWorker : BackgroundService using var scope = _serviceProvider.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService(); - var partidos = await dbContext.AmbitosGeograficos - .AsNoTracking() + // La obtención de partidos y categorías no cambia + var partidos = await dbContext.AmbitosGeograficos.AsNoTracking() .Where(a => a.NivelId == 30 && a.DistritoId != null && a.SeccionId != null) .ToListAsync(stoppingToken); - - var categorias = await dbContext.CategoriasElectorales - .AsNoTracking() - .ToListAsync(stoppingToken); + var categorias = await dbContext.CategoriasElectorales.AsNoTracking().ToListAsync(stoppingToken); if (!partidos.Any() || !categorias.Any()) return; @@ -748,13 +745,13 @@ public class LowPriorityDataWorker : BackgroundService if (listaTelegramasApi is { Count: > 0 }) { + // Creamos el DbContext para la operación de guardado using var innerScope = _serviceProvider.CreateScope(); var innerDbContext = innerScope.ServiceProvider.GetRequiredService(); var idsYaEnDb = await innerDbContext.Telegramas .Where(t => listaTelegramasApi.Contains(t.Id)) - .Select(t => t.Id) - .ToListAsync(stoppingToken); + .Select(t => t.Id).ToListAsync(stoppingToken); var nuevosTelegramasIds = listaTelegramasApi.Except(idsYaEnDb).ToList(); @@ -762,58 +759,69 @@ public class LowPriorityDataWorker : BackgroundService { _logger.LogInformation("Se encontraron {count} telegramas nuevos en '{partido}' para '{cat}'. Descargando...", nuevosTelegramasIds.Count, partido.Nombre, categoria.Nombre); - int contadorLote = 0; - const int tamanoLote = 5; // Cantidad a Guarda Por Lote - - foreach (var mesaId in nuevosTelegramasIds) + var originalTimeout = innerDbContext.Database.GetCommandTimeout(); + try { - if (stoppingToken.IsCancellationRequested) return; + innerDbContext.Database.SetCommandTimeout(180); + _logger.LogDebug("Timeout de BD aumentado a 180s para descarga de telegramas."); - var telegramaFile = await _apiService.GetTelegramaFileAsync(authToken, mesaId); - if (telegramaFile != null) + int contadorLote = 0; + const int tamanoLote = 100; + + foreach (var mesaId in nuevosTelegramasIds) { - var ambitoMesa = await innerDbContext.AmbitosGeograficos.AsNoTracking() - .FirstOrDefaultAsync(a => a.MesaId == mesaId, stoppingToken); + if (stoppingToken.IsCancellationRequested) return; - if (ambitoMesa != null) + var telegramaFile = await _apiService.GetTelegramaFileAsync(authToken, mesaId); + if (telegramaFile != null) { - var nuevoTelegrama = new Telegrama + var ambitoMesa = await innerDbContext.AmbitosGeograficos.AsNoTracking() + .FirstOrDefaultAsync(a => a.MesaId == mesaId, stoppingToken); + + if (ambitoMesa != null) { - Id = telegramaFile.NombreArchivo, - // 3. Usamos el ID del ÁMBITO DE LA MESA, no el del municipio. - AmbitoGeograficoId = ambitoMesa.Id, - ContenidoBase64 = telegramaFile.Imagen, - FechaEscaneo = DateTime.Parse(telegramaFile.FechaEscaneo).ToUniversalTime(), - FechaTotalizacion = DateTime.Parse(telegramaFile.FechaTotalizacion).ToUniversalTime() - }; - await innerDbContext.Telegramas.AddAsync(nuevoTelegrama, stoppingToken); - contadorLote++; // Incrementamos el contador + var nuevoTelegrama = new Telegrama + { + Id = telegramaFile.NombreArchivo, + AmbitoGeograficoId = ambitoMesa.Id, + ContenidoBase64 = telegramaFile.Imagen, + FechaEscaneo = DateTime.Parse(telegramaFile.FechaEscaneo).ToUniversalTime(), + FechaTotalizacion = DateTime.Parse(telegramaFile.FechaTotalizacion).ToUniversalTime() + }; + await innerDbContext.Telegramas.AddAsync(nuevoTelegrama, stoppingToken); + contadorLote++; + } + else + { + _logger.LogWarning("No se encontró un ámbito geográfico para la mesa con MesaId {MesaId}. El telegrama no será guardado.", mesaId); + } } - else + await Task.Delay(250, stoppingToken); + + if (contadorLote >= tamanoLote) { - _logger.LogWarning("No se encontró un ámbito geográfico para la mesa con MesaId {MesaId}. El telegrama no será guardado.", mesaId); + await innerDbContext.SaveChangesAsync(stoppingToken); + _logger.LogInformation("Guardado un lote de {count} telegramas.", contadorLote); + contadorLote = 0; } } - await Task.Delay(250, stoppingToken); // Mantenemos el delay para no saturar la API - // Si hemos alcanzado el tamaño del lote, guardamos y reseteamos. - if (contadorLote >= tamanoLote) + if (contadorLote > 0) { await innerDbContext.SaveChangesAsync(stoppingToken); - _logger.LogInformation("Guardado un lote de {count} telegramas.", contadorLote); - contadorLote = 0; // Reseteamos el contador para el siguiente lote + _logger.LogInformation("Guardado el último lote de {count} telegramas.", contadorLote); } } - - // Guardamos cualquier registro restante que no haya completado un lote completo. - if (contadorLote > 0) + finally { - await innerDbContext.SaveChangesAsync(stoppingToken); - _logger.LogInformation("Guardado el último lote de {count} telegramas.", contadorLote); + innerDbContext.Database.SetCommandTimeout(originalTimeout); + _logger.LogDebug("Timeout de BD restaurado a su valor original ({timeout}s).", originalTimeout); } - } - } - await Task.Delay(100, stoppingToken); + } // Fin del if (nuevosTelegramasIds.Any()) + + // Movemos el delay aquí para que solo se ejecute si hubo telegramas en la respuesta de la API + await Task.Delay(100, stoppingToken); + } // Fin del if (listaTelegramasApi is not null) } } _logger.LogInformation("Sondeo de Telegramas completado.");