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 @@ -12,9 +12,14 @@ public interface IGeneralDrivelution
/// </summary>
/// <param name="driverInfo">Driver information</param>
/// <param name="strategy">Update strategy</param>
/// <param name="progress">Optional progress reporter for real-time status updates.</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Update result</returns>
Task<UpdateResult> UpdateAsync(DriverInfo driverInfo, UpdateStrategy strategy, CancellationToken cancellationToken = default);
Task<UpdateResult> UpdateAsync(
DriverInfo driverInfo,
UpdateStrategy strategy,
IProgress<UpdateProgress>? progress = null,
CancellationToken cancellationToken = default);

/// <summary>
/// Validates driver asynchronously
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using GeneralUpdate.Drivelution.Abstractions.Models;

namespace GeneralUpdate.Drivelution.Abstractions.Models;

/// <summary>
/// Progress information reported during a driver update operation.
/// Suitable for binding to UI progress bars and status displays.
/// </summary>
public class UpdateProgress
{
/// <summary>
/// Current update status in the pipeline.
/// </summary>
public UpdateStatus CurrentStatus { get; init; }

/// <summary>
/// Name of the currently executing pipeline step.
/// </summary>
public string StepName { get; init; } = string.Empty;

/// <summary>
/// Overall completion percentage (0-100).
/// </summary>
public int Percentage { get; init; }

/// <summary>
/// Human-readable progress message.
/// </summary>
public string Message { get; init; } = string.Empty;

/// <summary>
/// Index of the current step (0-based).
/// </summary>
public int StepIndex { get; init; }

/// <summary>
/// Total number of steps in the pipeline.
/// </summary>
public int TotalSteps { get; init; }

/// <inheritdoc/>
public override string ToString()
=> $"[{Percentage}%] {StepName} ({StepIndex + 1}/{TotalSteps}): {Message}";
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ protected BaseDriverUpdater(
public async Task<UpdateResult> UpdateAsync(
DriverInfo driverInfo,
UpdateStrategy strategy,
IProgress<UpdateProgress>? progress = null,
CancellationToken cancellationToken = default)
{
var result = new UpdateResult
Expand All @@ -70,6 +71,7 @@ public async Task<UpdateResult> UpdateAsync(
using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(
cancellationToken, timeoutCts.Token);

int stepCount = 0;
try
{
GeneralTracer.Info($"Starting driver update: {driverInfo.Name} v{driverInfo.Version} " +
Expand All @@ -78,16 +80,26 @@ public async Task<UpdateResult> UpdateAsync(
var steps = GetPipelineSteps(strategy)
.Where(s => s.ShouldExecute(context))
.ToList();
stepCount = steps.Count;

var totalSteps = steps.Count;
var totalSteps = stepCount;
int stepIndex = 0;
PipelineResult? lastStepResult = null;

foreach (var step in steps)
{
stepIndex++;
OnStepStarted?.Invoke(step.StepName);
ReportProgress((int)((float)(stepIndex - 1) / totalSteps * 100), $"Running: {step.StepName}");

progress?.Report(new UpdateProgress
{
CurrentStatus = UpdateStatus.Updating,
StepName = step.StepName,
Percentage = (int)((float)(stepIndex - 1) / totalSteps * 100),
Message = $"Running: {step.StepName}",
StepIndex = stepIndex - 1,
TotalSteps = totalSteps
});

// Execute step with retry on transient failures
try
Expand Down Expand Up @@ -179,7 +191,17 @@ public async Task<UpdateResult> UpdateAsync(
{
result.EndTime = DateTime.UtcNow;
GeneralTracer.Info($"Driver update finished. Duration={result.DurationMs}ms, Success={result.Success}");
ReportProgress(100, result.Success ? "Completed" : "Failed");

progress?.Report(new UpdateProgress
{
CurrentStatus = result.Status,
StepName = result.Success ? "Completed" : "Failed",
Percentage = 100,
Message = result.Success ? "Driver update completed successfully" : result.Error?.Message ?? "Failed",
StepIndex = stepCount,
TotalSteps = stepCount
});

OnUpdateCompleted?.Invoke(result);
}

Expand Down
6 changes: 4 additions & 2 deletions src/c#/GeneralUpdate.Drivelution/GeneralDrivelution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public static IGeneralDrivelution Create(IServiceProvider serviceProvider)
/// <returns>Update result</returns>
public static async Task<UpdateResult> QuickUpdateAsync(
DriverInfo driverInfo,
IProgress<UpdateProgress>? progress = null,
CancellationToken cancellationToken = default)
{
GeneralTracer.Info($"GeneralDrivelution.QuickUpdateAsync: starting quick driver update. Driver={driverInfo.Name}, Version={driverInfo.Version}");
Expand All @@ -71,7 +72,7 @@ public static async Task<UpdateResult> QuickUpdateAsync(
RetryIntervalSeconds = 5
};

var result = await updater.UpdateAsync(driverInfo, strategy, cancellationToken);
var result = await updater.UpdateAsync(driverInfo, strategy, progress, cancellationToken);
GeneralTracer.Info($"GeneralDrivelution.QuickUpdateAsync: quick driver update completed. Success={result.Success}, Status={result.Status}, DurationMs={result.DurationMs}");
return result;
}
Expand All @@ -86,11 +87,12 @@ public static async Task<UpdateResult> QuickUpdateAsync(
public static async Task<UpdateResult> QuickUpdateAsync(
DriverInfo driverInfo,
UpdateStrategy strategy,
IProgress<UpdateProgress>? progress = null,
CancellationToken cancellationToken = default)
{
GeneralTracer.Info($"GeneralDrivelution.QuickUpdateAsync(strategy): starting driver update with custom strategy. Driver={driverInfo.Name}, Version={driverInfo.Version}, RequireBackup={strategy.RequireBackup}, RetryCount={strategy.RetryCount}");
var updater = Create();
var result = await updater.UpdateAsync(driverInfo, strategy, cancellationToken);
var result = await updater.UpdateAsync(driverInfo, strategy, progress, cancellationToken);
GeneralTracer.Info($"GeneralDrivelution.QuickUpdateAsync(strategy): driver update completed. Success={result.Success}, Status={result.Status}, DurationMs={result.DurationMs}");
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class MacOsGeneralDrivelution : IGeneralDrivelution
public Task<UpdateResult> UpdateAsync(
DriverInfo driverInfo,
UpdateStrategy strategy,
IProgress<UpdateProgress>? progress = null,
CancellationToken cancellationToken = default)
{
throw new PlatformNotSupportedException(
Expand Down
Loading