Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ private static void RegisterLoggingAndConsoleServices(IServiceCollection service
.AddSingleton<IPrimaryExceptionContainer, PrimaryExceptionContainer>()
.AddSingleton<ISecondaryExceptionContainer, SecondaryExceptionContainer>()
.AddSingleton<IExceptionRethrowService, ExceptionRethrowService>()

// Progress display components (SRP extraction from ProgressPrinter)
.AddSingleton<IProgressCalculator, ProgressCalculator>()
.AddSingleton<IProgressDisplay, SpectreProgressDisplay>()
.AddSingleton<IResultsPrinter, SpectreResultsPrinter>()
.AddSingleton<ProgressPrinter>()
.AddSingleton<IProgressPrinter>(sp => sp.GetRequiredService<ProgressPrinter>())
.AddSingleton<ILogoPrinter, LogoPrinter>()
Expand Down
27 changes: 27 additions & 0 deletions src/ModularPipelines/Helpers/IProgressCalculator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace ModularPipelines.Helpers;

/// <summary>
/// Provides progress calculation logic for module execution tracking.
/// </summary>
internal interface IProgressCalculator
{
/// <summary>
/// Calculates the tick information for progress updates based on estimated duration.
/// </summary>
/// <param name="estimatedDuration">The estimated duration for the module.</param>
/// <returns>Information about how to tick progress.</returns>
ProgressTickInfo CalculateTickInfo(TimeSpan estimatedDuration);

/// <summary>
/// Calculates the progress increment for total progress when a module completes.
/// </summary>
/// <param name="totalModuleCount">Total number of modules in the pipeline.</param>
/// <returns>The progress increment percentage.</returns>
double CalculateProgressIncrement(int totalModuleCount);
}

/// <summary>
/// Contains calculated tick information for progress updates.
/// </summary>
/// <param name="TicksPerSecond">Number of progress ticks to add per second.</param>
internal readonly record struct ProgressTickInfo(double TicksPerSecond);
54 changes: 54 additions & 0 deletions src/ModularPipelines/Helpers/IProgressDisplay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using ModularPipelines.Engine;
using ModularPipelines.Models;
using ModularPipelines.Modules;

namespace ModularPipelines.Helpers;

/// <summary>
/// Abstraction for displaying module execution progress.
/// Separates the display mechanism from the notification handling logic.
/// </summary>
internal interface IProgressDisplay
{
/// <summary>
/// Starts the progress display and keeps it running until completion or cancellation.
/// </summary>
/// <param name="organizedModules">The modules to track progress for.</param>
/// <param name="cancellationToken">Token to signal cancellation.</param>
Task RunAsync(OrganizedModules organizedModules, CancellationToken cancellationToken);

/// <summary>
/// Registers a module as started and begins tracking its progress.
/// </summary>
/// <param name="moduleState">The state of the started module.</param>
/// <param name="estimatedDuration">Estimated time for the module to complete.</param>
void OnModuleStarted(ModuleState moduleState, TimeSpan estimatedDuration);

/// <summary>
/// Updates display when a module completes execution.
/// </summary>
/// <param name="moduleState">The state of the completed module.</param>
/// <param name="isSuccessful">Whether the module completed successfully.</param>
void OnModuleCompleted(ModuleState moduleState, bool isSuccessful);

/// <summary>
/// Updates display when a module is skipped.
/// </summary>
/// <param name="moduleState">The state of the skipped module.</param>
void OnModuleSkipped(ModuleState moduleState);

/// <summary>
/// Registers a sub-module as created and begins tracking its progress.
/// </summary>
/// <param name="parentModule">The parent module that created the sub-module.</param>
/// <param name="subModule">The created sub-module.</param>
/// <param name="estimatedDuration">Estimated time for the sub-module to complete.</param>
void OnSubModuleCreated(IModule parentModule, SubModuleBase subModule, TimeSpan estimatedDuration);

/// <summary>
/// Updates display when a sub-module completes.
/// </summary>
/// <param name="subModule">The completed sub-module.</param>
/// <param name="isSuccessful">Whether the sub-module completed successfully.</param>
void OnSubModuleCompleted(SubModuleBase subModule, bool isSuccessful);
}
14 changes: 13 additions & 1 deletion src/ModularPipelines/Helpers/IProgressPrinter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@

namespace ModularPipelines.Helpers;

/// <summary>
/// Coordinates progress display and results printing for pipeline execution.
/// </summary>
internal interface IProgressPrinter
{
/// <summary>
/// Displays real-time progress of module execution.
/// </summary>
/// <param name="organizedModules">The organized modules to track.</param>
/// <param name="cancellationToken">Token to signal cancellation.</param>
Task PrintProgress(OrganizedModules organizedModules, CancellationToken cancellationToken);

/// <summary>
/// Prints the final results summary after pipeline completion.
/// </summary>
/// <param name="pipelineSummary">The pipeline execution summary.</param>
void PrintResults(PipelineSummary pipelineSummary);
}
}
16 changes: 16 additions & 0 deletions src/ModularPipelines/Helpers/IResultsPrinter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using ModularPipelines.Models;

namespace ModularPipelines.Helpers;

/// <summary>
/// Abstraction for printing pipeline execution results.
/// Separates results presentation from the progress tracking logic.
/// </summary>
internal interface IResultsPrinter
{
/// <summary>
/// Prints a summary of the pipeline execution results.
/// </summary>
/// <param name="pipelineSummary">The summary containing execution results.</param>
void PrintResults(PipelineSummary pipelineSummary);
}
35 changes: 35 additions & 0 deletions src/ModularPipelines/Helpers/ProgressCalculator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace ModularPipelines.Helpers;

/// <summary>
/// Provides progress calculation logic for module execution tracking.
/// </summary>
internal class ProgressCalculator : IProgressCalculator
{
private const double HeadroomMultiplier = 1.1; // Give 10% headroom
private const double MinEstimatedSeconds = 1.0;
private const double TotalProgressPercentage = 100.0;

/// <inheritdoc />
public ProgressTickInfo CalculateTickInfo(TimeSpan estimatedDuration)
{
var estimatedWithHeadroom = estimatedDuration * HeadroomMultiplier;
var totalEstimatedSeconds = estimatedWithHeadroom.TotalSeconds >= MinEstimatedSeconds
? estimatedWithHeadroom.TotalSeconds
: MinEstimatedSeconds;

var ticksPerSecond = TotalProgressPercentage / totalEstimatedSeconds;

return new ProgressTickInfo(ticksPerSecond);
}

/// <inheritdoc />
public double CalculateProgressIncrement(int totalModuleCount)
{
if (totalModuleCount <= 0)
{
return 0;
}

return TotalProgressPercentage / totalModuleCount;
}
}
Loading
Loading