perf(Worker): Implementa ejecución paralela de fetchers para mejorar rendimiento
This commit is contained in:
@@ -67,40 +67,31 @@ namespace Mercados.Worker
|
||||
private async Task RunScheduledTasksAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
var utcNow = DateTime.UtcNow;
|
||||
|
||||
// Obtenemos las expresiones Cron desde la configuración
|
||||
|
||||
// Tareas diarias (estas suelen ser rápidas y no se solapan, no es crítico paralelizar)
|
||||
// Mantenerlas secuenciales puede ser más simple de leer.
|
||||
string? agroSchedule = _configuration["Schedules:MercadoAgroganadero"];
|
||||
string? bcrSchedule = _configuration["Schedules:BCR"];
|
||||
string? bolsasSchedule = _configuration["Schedules:Bolsas"];
|
||||
|
||||
// Comprobamos cada una antes de usarla
|
||||
if (!string.IsNullOrEmpty(agroSchedule))
|
||||
{
|
||||
await TryRunDailyTaskAsync("MercadoAgroganadero", agroSchedule, utcNow, stoppingToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("No se encontró la configuración de horario para 'MercadoAgroganadero' en appsettings.json.");
|
||||
}
|
||||
else { _logger.LogWarning("..."); }
|
||||
|
||||
string? bcrSchedule = _configuration["Schedules:BCR"];
|
||||
if (!string.IsNullOrEmpty(bcrSchedule))
|
||||
{
|
||||
await TryRunDailyTaskAsync("BCR", bcrSchedule, utcNow, stoppingToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("No se encontró la configuración de horario para 'BCR' en appsettings.json.");
|
||||
}
|
||||
else { _logger.LogWarning("..."); }
|
||||
|
||||
// --- Tareas Recurrentes (Bolsas) ---
|
||||
string? bolsasSchedule = _configuration["Schedules:Bolsas"];
|
||||
if (!string.IsNullOrEmpty(bolsasSchedule))
|
||||
{
|
||||
await TryRunRecurringTaskAsync(new[] { "YahooFinance", "Finnhub" }, bolsasSchedule, utcNow, stoppingToken);
|
||||
// Reemplazamos la llamada secuencial con la ejecución paralela
|
||||
await TryRunRecurringTaskInParallelAsync(new[] { "YahooFinance", "Finnhub" }, bolsasSchedule, utcNow, stoppingToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("No se encontró la configuración de horario para 'Bolsas' en appsettings.json.");
|
||||
}
|
||||
// --- ^ FIN DE LA CORRECCIÓN DE NULABILIDAD ^ ---
|
||||
else { _logger.LogWarning("..."); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -124,20 +115,22 @@ namespace Mercados.Worker
|
||||
/// <summary>
|
||||
/// Comprueba y ejecuta una tarea que puede correr múltiples veces al día.
|
||||
/// </summary>
|
||||
private async Task TryRunRecurringTaskAsync(string[] taskNames, string cronExpression, DateTime utcNow, CancellationToken stoppingToken)
|
||||
private async Task TryRunRecurringTaskInParallelAsync(string[] taskNames, string cronExpression, DateTime utcNow, CancellationToken stoppingToken)
|
||||
{
|
||||
// Añadimos 'IncludeSeconds' para que la comparación sea precisa y no se ejecute dos veces en el mismo minuto.
|
||||
var cron = CronExpression.Parse(cronExpression, CronFormat.IncludeSeconds);
|
||||
// Comprobamos si hubo una ocurrencia en el último minuto.
|
||||
var nextOccurrence = cron.GetNextOccurrence(utcNow.AddMinutes(-1));
|
||||
|
||||
if (nextOccurrence.HasValue && nextOccurrence.Value <= utcNow)
|
||||
{
|
||||
_logger.LogInformation("Ventana de ejecución recurrente detectada para: {Tasks}", string.Join(", ", taskNames));
|
||||
foreach (var taskName in taskNames)
|
||||
{
|
||||
await RunFetcherByNameAsync(taskName, stoppingToken);
|
||||
}
|
||||
_logger.LogInformation("Ventana de ejecución para: {Tasks}. Iniciando en paralelo...", string.Join(", ", taskNames));
|
||||
|
||||
// Creamos una lista de tareas, una por cada fetcher a ejecutar
|
||||
var tasks = taskNames.Select(taskName => RunFetcherByNameAsync(taskName, stoppingToken)).ToList();
|
||||
|
||||
// Iniciamos todas las tareas a la vez y esperamos a que todas terminen
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
_logger.LogInformation("Todas las tareas recurrentes han finalizado.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,14 +171,17 @@ namespace Mercados.Worker
|
||||
/*
|
||||
private async Task RunAllFetchersAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
_logger.LogInformation("Ejecutando todos los fetchers al iniciar...");
|
||||
_logger.LogInformation("Ejecutando todos los fetchers al iniciar en paralelo...");
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
var fetchers = scope.ServiceProvider.GetRequiredService<IEnumerable<IDataFetcher>>();
|
||||
foreach (var fetcher in fetchers)
|
||||
{
|
||||
if (stoppingToken.IsCancellationRequested) break;
|
||||
await RunFetcherByNameAsync(fetcher.SourceName, stoppingToken);
|
||||
}
|
||||
|
||||
// Creamos una lista de tareas, una por cada fetcher disponible
|
||||
var tasks = fetchers.Select(fetcher => RunFetcherByNameAsync(fetcher.SourceName, stoppingToken)).ToList();
|
||||
|
||||
// Ejecutamos todo y esperamos
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
_logger.LogInformation("Ejecución inicial de todos los fetchers completada.");
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user