public override void QueueTask(Processable processable) { if (isStopped) { throw new Exception("Cannot call QueueTask when stopped"); } nextTasks.Add(processable); }
protected static async Task RunAsync(Processable Processable) { foreach (var libraryBook in Processable.GetValidLibraryBooks(DbContexts.GetLibrary_Flat_NoTracking())) { await ProcessOneAsync(Processable, libraryBook, false); } var done = "Done. All books have been processed"; Console.WriteLine(done); Serilog.Log.Logger.Information(done); }
public void ContinueExecution(Processable task) { if (IsStopped()) { throw new System.Exception("Cannot continue execution on graph that is not running"); } if (Events.OnResume != null && IsIdle()) { Events.OnResume.Invoke(); } _ContinueExecutionOn(task); }
protected override void _ContinueExecutionOn(Processable task) { if (state == ExecutorState.Idle) { state = ExecutorState.ProcessingTasks; context.Continue(); context.QueueTask(task); Loop(); } else { // We're already in the loop, just queue up the tasks context.QueueTask(task); } }
private static async Task ProcessOneAsync(Processable Processable, LibraryBook libraryBook, bool validate) { try { var statusHandler = await Processable.ProcessSingleAsync(libraryBook, validate); if (statusHandler.IsSuccess) { return; } foreach (var errorMessage in statusHandler.Errors) { Serilog.Log.Logger.Error(errorMessage); } } catch (Exception ex) { var msg = "Error processing book. Skipping. This book will be tried again on next attempt. For options of skipping or marking as error, retry with main Libation app."; Console.WriteLine(msg + ". See log for more details."); Serilog.Log.Logger.Error(ex, $"{msg} {{@DebugInfo}}", new { Book = libraryBook.LogFriendly() }); } }
public void Process(Processable a) { Process((AProcessable)a); Process((BProcessable)a); }
public void Loop() { switch (state) { case ExecutorState.Stopped: return; case ExecutorState.Idle: throw new Exception("Executor attempted to run loop while in idle state"); case ExecutorState.ProcessingTasks: if (p != null) { // Process next and unhighlight p.Process(context); if (!p.HasMoreToProcess()) { p.DebugUnhighlight(); p = null; } // Repeat loop Loop(); } else if (context.tasksEnumerator.MoveNext()) { // Get next node to process p = context.tasksEnumerator.Current; // Highlight the node p.DebugHighlight(); // Repeat loop Loop(); } else // Finished with the current tasks // Go back to queuing tasks { state = ExecutorState.QueuingTasks; // Repeat loop, no delay Loop(); } break; case ExecutorState.QueuingTasks: if (context.HasNewlyEnqueuedTasks()) // If there is something to process gathered from the previous processes, do them // Swap processing lists and clear the next processing list { context.SwitchToNewlyEnqueuedTasks(); // Start processing again state = ExecutorState.ProcessingTasks; // Repeat loop, no delay Loop(); } else if (HasInitialisingTasks()) // Otherwise if there is data to process gathered from elsewhere, do that { EnqueueNextInitialisingTask(); // Start processing again state = ExecutorState.ProcessingTasks; // Repeat loop, no delay Loop(); } else // If there is no data, stop/idle the execution { if (Graph.HasSubscriptions() || Graph.HasDelayedExecution()) { // Idle if the graph is still has active external connections state = ExecutorState.Idle; if (Events.OnIdle != null) { Events.OnIdle.Invoke(); } } else { // Stop if there are no component externally connected StopExecution(); } } break; } }
protected abstract void _ContinueExecutionOn(Processable tasks);
public abstract void QueueTask(Processable processable);