Fase 5: Implementada la configuración dinámica. Implementado el scraping web.
This commit is contained in:
		
							
								
								
									
										77
									
								
								backend/src/Titulares.Api/Workers/ProcesoScrapingWorker.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								backend/src/Titulares.Api/Workers/ProcesoScrapingWorker.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| // backend/src/Titulares.Api/Workers/ProcesoScrapingWorker.cs | ||||
|  | ||||
| using Microsoft.AspNetCore.SignalR; | ||||
| using Titulares.Api.Data; | ||||
| using Titulares.Api.Hubs; | ||||
| using Titulares.Api.Services; | ||||
| using Microsoft.Extensions.Options; | ||||
| using Titulares.Api.Models; | ||||
|  | ||||
| namespace Titulares.Api.Workers; | ||||
|  | ||||
| public class ProcesoScrapingWorker : BackgroundService | ||||
| { | ||||
|   private readonly ILogger<ProcesoScrapingWorker> _logger; | ||||
|   private readonly IServiceProvider _serviceProvider; | ||||
|   private readonly IOptionsMonitor<ConfiguracionApp> _configuracion; | ||||
|  | ||||
|   public ProcesoScrapingWorker(ILogger<ProcesoScrapingWorker> logger, IServiceProvider serviceProvider, IOptionsMonitor<ConfiguracionApp> configuracion) | ||||
|   { | ||||
|     _logger = logger; | ||||
|     _serviceProvider = serviceProvider; | ||||
|     _configuracion = configuracion; | ||||
|   } | ||||
|  | ||||
|   protected override async Task ExecuteAsync(CancellationToken stoppingToken) | ||||
|   { | ||||
|     while (!stoppingToken.IsCancellationRequested) | ||||
|     { | ||||
|       var configActual = _configuracion.CurrentValue; | ||||
|  | ||||
|       _logger.LogInformation("Iniciando ciclo de scraping con cantidad: {cantidad}", configActual.CantidadTitularesAScrapear); | ||||
|  | ||||
|       try | ||||
|       { | ||||
|         // Creamos un 'scope' para obtener instancias 'scoped' de nuestros servicios. | ||||
|         // Es la práctica correcta en servicios de larga duración. | ||||
|         using (var scope = _serviceProvider.CreateScope()) | ||||
|         { | ||||
|           var repositorio = scope.ServiceProvider.GetRequiredService<TitularRepositorio>(); | ||||
|           var scrapingService = scope.ServiceProvider.GetRequiredService<ScrapingService>(); | ||||
|           var hubContext = scope.ServiceProvider.GetRequiredService<IHubContext<TitularesHub>>(); | ||||
|  | ||||
|           // Obtener estos valores desde la configuración | ||||
|           int cantidadAObtener = configActual.CantidadTitularesAScrapear; | ||||
|           int limiteTotalEnDb = configActual.LimiteTotalEnDb; | ||||
|  | ||||
|           // 1. Obtener los últimos titulares de la web | ||||
|           var articulosScrapeados = await scrapingService.ObtenerUltimosTitulares(cantidadAObtener); | ||||
|  | ||||
|           if (articulosScrapeados.Any()) | ||||
|           { | ||||
|             // 2. Sincronizar con la base de datos | ||||
|             await repositorio.SincronizarDesdeScraping(articulosScrapeados, limiteTotalEnDb); | ||||
|             _logger.LogInformation("Sincronización con la base de datos completada."); | ||||
|  | ||||
|             // 3. Notificar a todos los clientes a través de SignalR | ||||
|             var titularesActualizados = await repositorio.ObtenerTodosAsync(); | ||||
|             await hubContext.Clients.All.SendAsync("TitularesActualizados", titularesActualizados, stoppingToken); | ||||
|             _logger.LogInformation("Notificación enviada a los clientes."); | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|             _logger.LogWarning("No se encontraron artículos en el scraping."); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       catch (Exception ex) | ||||
|       { | ||||
|         _logger.LogError(ex, "Ocurrió un error durante el proceso de scraping."); | ||||
|       } | ||||
|  | ||||
|       var intervaloEnMinutos = configActual.IntervaloMinutos; | ||||
|       _logger.LogInformation("Proceso en espera por {minutos} minutos.", intervaloEnMinutos); | ||||
|       await Task.Delay(TimeSpan.FromMinutes(intervaloEnMinutos), stoppingToken); | ||||
|     } | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user