using System.Threading; using System; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.DependencyInjection; using AyaNova.Models; using AyaNova.Api.ControllerHelpers; using AyaNova.Biz; using AyaNova.Util; namespace AyaNova.Generator { //Implemented from a example here //https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/multi-container-microservice-net-applications/background-tasks-with-ihostedservice /* LOOKAT: Generator tasks that should happen: - Periodically erase any temp files written to userfiles root (attachments temp files) that are older than a day - These files should be normally erased within seconds after uploading and processing into their permanent folder but shit will go wrong */ public class GeneratorService : BackgroundService { private readonly ILogger log; // private readonly AyContext ct; // private readonly ApiServerState serverState; private readonly IServiceProvider provider; private const int MAXIMUM_TIME_ALLOWED_FOR_PROCESSING_ALL_JOBS = 1 * 60 * 1000;//1 minutes TEST TEST TEST ##### #if(DEBUG) private const int GENERATE_SECONDS = 5; #else private const int GENERATE_SECONDS = 20; #endif // public GeneratorService(ILogger logger, AyContext dbcontext, ApiServerState apiServerState) // { // ct = dbcontext; // log = logger; // serverState = apiServerState; // } public GeneratorService(ILogger logger, IServiceProvider serviceProvider) { // ct = dbcontext; provider = serviceProvider; log = logger; // serverState = apiServerState; } /* todo: improve this it should timeout: https://stackoverflow.com/questions/23476576/cancellationtoken-timeout-vs-task-delay-and-timeout it should never stop running no matter what unless teh server shuts down */ protected override async Task ExecuteAsync(CancellationToken stoppingToken) { //don't immediately run the generator stuff on boot bool justStarted = true; log.LogDebug($"GeneratorService is starting."); stoppingToken.Register(() => log.LogDebug($" GeneratorService background task is stopping.")); while (!stoppingToken.IsCancellationRequested) { if (!justStarted) { log.LogDebug($"GeneratorService task doing background work."); ApiServerState serverState = ServiceProviderProvider.ServerState; //================================================================= try { if (!serverState.IsOpen) { log.LogDebug($"GeneratorService: ServerState is closed returning without processing jobs, will try again next iteration"); } else { System.Diagnostics.Debug.WriteLine($"### GENERATE calling JobsBiz.ProcessJobs"); //Before anything capture metrics // await CoreJobMetricsSnapshot.DoJobAsync(ct); //Task.Run(() => CoreJobMetricsSnapshot.DoJob()); //deliberately calling this non-async //it needs to be fast and efficient CoreJobMetricsSnapshot.DoJob(); //TODO: this should be big timeout and then inside the process jobs each job has it's own timeout await TaskUtil.WithTimeoutAfterStart(ctoken => JobsBiz.ProcessJobsAsync(ctoken), TimeSpan.FromMilliseconds(MAXIMUM_TIME_ALLOWED_FOR_PROCESSING_ALL_JOBS)); // await JobsBiz.ProcessJobsAsync(ct, serverState); System.Diagnostics.Debug.WriteLine($"### GENERATE BACK FROM calling JobsBiz.ProcessJobs"); } } catch (Exception ex) { log.LogError(ex, "Generate::ProcessJobs result in exception error "); } //================================================================= } await Task.Delay((GENERATE_SECONDS * 1000), stoppingToken); justStarted = false; } log.LogDebug($"GeneratorService background task is stopping."); } //originally but kept getting compiler error // public override async Task StopAsync(CancellationToken stoppingToken) // { // log.LogDebug($"GeneratorService StopAsync triggered."); // // Run your graceful clean-up actions // } public override Task StopAsync(CancellationToken stoppingToken) { log.LogDebug($"GeneratorService StopAsync triggered."); return Task.FromResult(0); // Run your graceful clean-up actions } } }