From f8ccd2d69efb9a28b6121b17e80843e51bbd9e5e Mon Sep 17 00:00:00 2001 From: glax Date: Thu, 3 Jul 2025 20:51:06 +0200 Subject: [PATCH] Tranga WorkerCycle --- API/Controllers/WorkerController.cs | 16 +++++------ API/Tranga.cs | 41 ++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/API/Controllers/WorkerController.cs b/API/Controllers/WorkerController.cs index a0f66af..39ea00d 100644 --- a/API/Controllers/WorkerController.cs +++ b/API/Controllers/WorkerController.cs @@ -21,7 +21,7 @@ public class WorkerController(ILog Log) : Controller [ProducesResponseType(Status200OK, "application/json")] public IActionResult GetAllWorkers() { - return Ok(Tranga.Workers.ToArray()); + return Ok(Tranga.AllWorkers.ToArray()); } /// @@ -33,7 +33,7 @@ public class WorkerController(ILog Log) : Controller [ProducesResponseType(Status200OK, "application/json")] public IActionResult GetJobs([FromBody]string[] WorkerIds) { - return Ok(Tranga.Workers.Where(worker => WorkerIds.Contains(worker.Key)).ToArray()); + return Ok(Tranga.AllWorkers.Where(worker => WorkerIds.Contains(worker.Key)).ToArray()); } /// @@ -45,7 +45,7 @@ public class WorkerController(ILog Log) : Controller [ProducesResponseType(Status200OK, "application/json")] public IActionResult GetJobsInState(WorkerExecutionState State) { - return Ok(Tranga.Workers.Where(worker => worker.State == State).ToArray()); + return Ok(Tranga.AllWorkers.Where(worker => worker.State == State).ToArray()); } /// @@ -59,7 +59,7 @@ public class WorkerController(ILog Log) : Controller [ProducesResponseType(Status404NotFound)] public IActionResult GetJob(string WorkerId) { - if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) + if(Tranga.AllWorkers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); return Ok(worker); } @@ -75,7 +75,7 @@ public class WorkerController(ILog Log) : Controller [ProducesResponseType(Status404NotFound)] public IActionResult DeleteJob(string WorkerId) { - if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) + if(Tranga.AllWorkers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); Tranga.RemoveWorker(worker); return Ok(); @@ -97,7 +97,7 @@ public class WorkerController(ILog Log) : Controller [ProducesResponseType(Status409Conflict, "text/plain")] public IActionResult ModifyJob(string WorkerId, [FromBody]ModifyWorkerRecord modifyWorkerRecord) { - if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) + if(Tranga.AllWorkers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); if(modifyWorkerRecord.IntervalMs is not null && worker is not IPeriodic) @@ -121,7 +121,7 @@ public class WorkerController(ILog Log) : Controller [ProducesResponseType(Status412PreconditionFailed, "text/plain")] public IActionResult StartJob(string WorkerId) { - if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) + if(Tranga.AllWorkers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); if (worker.State >= WorkerExecutionState.Waiting) @@ -142,7 +142,7 @@ public class WorkerController(ILog Log) : Controller [ProducesResponseType(Status501NotImplemented)] public IActionResult StopJob(string WorkerId) { - if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) + if(Tranga.AllWorkers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); if(worker.State is < WorkerExecutionState.Running or >= WorkerExecutionState.Completed) diff --git a/API/Tranga.cs b/API/Tranga.cs index b66ab77..fcb2edb 100644 --- a/API/Tranga.cs +++ b/API/Tranga.cs @@ -32,8 +32,8 @@ public static class Tranga Log.Info(TRANGA); } - internal static HashSet Workers { get; private set; } = new (); - public static void AddWorker(BaseWorker worker) => Workers.Add(worker); + internal static HashSet AllWorkers { get; private set; } = new (); + public static void AddWorker(BaseWorker worker) => AllWorkers.Add(worker); public static void AddWorkers(IEnumerable workers) { foreach (BaseWorker baseWorker in workers) @@ -42,21 +42,14 @@ public static class Tranga } } - internal static void StopWorker(BaseWorker worker) => RemoveWorker(worker); - public static void RemoveWorker(BaseWorker removeWorker) { - IEnumerable baseWorkers = Workers.Where(w => w.DependenciesAndSelf.Any(worker => worker == removeWorker)); + IEnumerable baseWorkers = AllWorkers.Where(w => w.DependenciesAndSelf.Any(worker => worker == removeWorker)); foreach (BaseWorker worker in baseWorkers) { - worker.Cancel(); - Workers.Remove(worker); - if (RunningWorkers.ContainsKey(worker)) - { - worker.Cancel(); - RunningWorkers.Remove(worker); - } + StopWorker(worker); + AllWorkers.Remove(worker); } } @@ -76,6 +69,9 @@ public static class Tranga while (true) { CheckRunningWorkers(); + + foreach (BaseWorker baseWorker in AllWorkers.DueWorkers()) + StartWorkers.Add(baseWorker); foreach (BaseWorker worker in StartWorkers) { @@ -96,12 +92,31 @@ public static class Tranga { RunningWorkers.Remove(worker); foreach (BaseWorker newWorker in task.Result) - StartWorkers.Add(newWorker); + AllWorkers.Add(newWorker); task.Dispose(); } } + private static IEnumerable DueWorkers(this IEnumerable workers) + { + return workers.Where(w => + { + if (w.State is >= WorkerExecutionState.Running and < WorkerExecutionState.Completed) + return false; + if (w is IPeriodic periodicWorker) + return periodicWorker.IsDue; + return true; + }); + } + internal static void MarkWorkerForStart(BaseWorker worker) => StartWorkers.Add(worker); + + internal static void StopWorker(BaseWorker worker) + { + StartWorkers.Remove(worker); + worker.Cancel(); + RunningWorkers.Remove(worker); + } internal static bool AddMangaToContext((Manga, MangaConnectorId) addManga, MangaContext context, [NotNullWhen(true)]out Manga? manga) => AddMangaToContext(addManga.Item1, addManga.Item2, context, out manga);