sprints work

This commit is contained in:
master
2026-01-11 11:19:40 +02:00
parent f6ef1ef337
commit 582a41d7a9
72 changed files with 2680 additions and 390 deletions

View File

@@ -108,6 +108,9 @@ builder.Services.AddSingleton<IPackRunIncidentModeService, PackRunIncidentModeSe
builder.Services.AddOpenApi();
// Determinism: TimeProvider injection
builder.Services.AddSingleton(TimeProvider.System);
// Stella Router integration
var routerOptions = builder.Configuration.GetSection("TaskRunner:Router").Get<StellaRouterOptionsBase>();
builder.Services.TryAddStellaRouter(
@@ -259,6 +262,7 @@ async Task<IResult> HandleCreateRun(
IPackRunJobScheduler scheduler,
ISealedInstallEnforcer sealedInstallEnforcer,
ISealedInstallAuditLogger auditLogger,
TimeProvider timeProvider,
CancellationToken cancellationToken)
{
if (request is null || string.IsNullOrWhiteSpace(request.Manifest))
@@ -315,7 +319,7 @@ async Task<IResult> HandleCreateRun(
}
},
status = "rejected",
rejected_at = DateTimeOffset.UtcNow.ToString("O", CultureInfo.InvariantCulture)
rejected_at = timeProvider.GetUtcNow().ToString("O", CultureInfo.InvariantCulture)
}, statusCode: StatusCodes.Status403Forbidden);
}
@@ -340,7 +344,7 @@ async Task<IResult> HandleCreateRun(
return Results.Conflict(new { error = "Run already exists." });
}
var requestedAt = DateTimeOffset.UtcNow;
var requestedAt = timeProvider.GetUtcNow();
var context = new PackRunExecutionContext(runId, plan, requestedAt, request.TenantId);
var graph = executionGraphBuilder.Build(plan);
@@ -355,7 +359,7 @@ async Task<IResult> HandleCreateRun(
{
await logStore.AppendAsync(
runId,
new PackRunLogEntry(DateTimeOffset.UtcNow, "error", "run.schedule-failed", ex.Message, null, null),
new PackRunLogEntry(timeProvider.GetUtcNow(), "error", "run.schedule-failed", ex.Message, null, null),
cancellationToken).ConfigureAwait(false);
return Results.StatusCode(StatusCodes.Status500InternalServerError);
@@ -373,7 +377,7 @@ async Task<IResult> HandleCreateRun(
await logStore.AppendAsync(
runId,
new PackRunLogEntry(DateTimeOffset.UtcNow, "info", "run.created", "Run created via API.", null, metadata),
new PackRunLogEntry(timeProvider.GetUtcNow(), "info", "run.created", "Run created via API.", null, metadata),
cancellationToken).ConfigureAwait(false);
var response = RunStateMapper.ToResponse(state);
@@ -510,6 +514,7 @@ async Task<IResult> HandleCancelRun(
string runId,
IPackRunStateStore stateStore,
IPackRunLogStore logStore,
TimeProvider timeProvider,
CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(runId))
@@ -523,7 +528,7 @@ async Task<IResult> HandleCancelRun(
return Results.NotFound();
}
var now = DateTimeOffset.UtcNow;
var now = timeProvider.GetUtcNow();
var updatedSteps = state.Steps.Values
.Select(step => step.Status is PackRunStepExecutionStatus.Succeeded or PackRunStepExecutionStatus.Skipped
? step
@@ -550,7 +555,7 @@ async Task<IResult> HandleCancelRun(
};
await logStore.AppendAsync(runId, new PackRunLogEntry(now, "warn", "run.cancel-requested", "Run cancellation requested.", null, metadata), cancellationToken).ConfigureAwait(false);
await logStore.AppendAsync(runId, new PackRunLogEntry(DateTimeOffset.UtcNow, "info", "run.cancelled", "Run cancelled; remaining steps marked as skipped.", null, metadata), cancellationToken).ConfigureAwait(false);
await logStore.AppendAsync(runId, new PackRunLogEntry(timeProvider.GetUtcNow(), "info", "run.cancelled", "Run cancelled; remaining steps marked as skipped.", null, metadata), cancellationToken).ConfigureAwait(false);
return Results.Accepted($"/v1/task-runner/runs/{runId}", new { status = "cancelled" });
}

View File

@@ -28,6 +28,7 @@ public sealed class PackRunWorkerService : BackgroundService
private readonly IPackRunArtifactUploader artifactUploader;
private readonly IPackRunProvenanceWriter provenanceWriter;
private readonly IPackRunLogStore logStore;
private readonly TimeProvider timeProvider;
private readonly ILogger<PackRunWorkerService> logger;
private readonly UpDownCounter<long> runningSteps;
@@ -42,6 +43,7 @@ public sealed class PackRunWorkerService : BackgroundService
IPackRunProvenanceWriter provenanceWriter,
IPackRunLogStore logStore,
IOptions<PackRunWorkerOptions> options,
TimeProvider timeProvider,
ILogger<PackRunWorkerService> logger)
{
this.dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
@@ -54,6 +56,7 @@ public sealed class PackRunWorkerService : BackgroundService
this.provenanceWriter = provenanceWriter ?? throw new ArgumentNullException(nameof(provenanceWriter));
this.logStore = logStore ?? throw new ArgumentNullException(nameof(logStore));
this.options = options?.Value ?? throw new ArgumentNullException(nameof(options));
this.timeProvider = timeProvider ?? TimeProvider.System;
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
runningSteps = TaskRunnerTelemetry.RunningSteps;
@@ -141,7 +144,7 @@ public sealed class PackRunWorkerService : BackgroundService
return;
}
var gateUpdate = PackRunGateStateUpdater.Apply(state, graph, processorResult.ApprovalCoordinator, DateTimeOffset.UtcNow);
var gateUpdate = PackRunGateStateUpdater.Apply(state, graph, processorResult.ApprovalCoordinator, timeProvider.GetUtcNow());
state = gateUpdate.State;
if (gateUpdate.HasBlockingFailure)
@@ -189,7 +192,7 @@ public sealed class PackRunWorkerService : BackgroundService
PackRunExecutionGraph graph,
CancellationToken cancellationToken)
{
var timestamp = DateTimeOffset.UtcNow;
var timestamp = timeProvider.GetUtcNow();
var state = PackRunStateFactory.CreateInitialState(context, graph, simulationEngine, timestamp);
await stateStore.SaveAsync(state, cancellationToken).ConfigureAwait(false);
return state;
@@ -204,7 +207,7 @@ public sealed class PackRunWorkerService : BackgroundService
string? stepId = null,
IReadOnlyDictionary<string, string>? metadata = null)
{
var entry = new PackRunLogEntry(DateTimeOffset.UtcNow, level, eventType, message, stepId, metadata);
var entry = new PackRunLogEntry(timeProvider.GetUtcNow(), level, eventType, message, stepId, metadata);
return logStore.AppendAsync(runId, entry, cancellationToken);
}
@@ -230,7 +233,7 @@ public sealed class PackRunWorkerService : BackgroundService
var updated = new ReadOnlyDictionary<string, PackRunStepStateRecord>(mutable);
return state with
{
UpdatedAt = DateTimeOffset.UtcNow,
UpdatedAt = timeProvider.GetUtcNow(),
Steps = updated
};
}
@@ -256,7 +259,7 @@ public sealed class PackRunWorkerService : BackgroundService
return StepExecutionOutcome.Continue;
}
if (record.NextAttemptAt is { } scheduled && scheduled > DateTimeOffset.UtcNow)
if (record.NextAttemptAt is { } scheduled && scheduled > timeProvider.GetUtcNow())
{
logger.LogInformation(
"Run {RunId} step {StepId} waiting until {NextAttempt} for retry.",
@@ -287,7 +290,7 @@ public sealed class PackRunWorkerService : BackgroundService
{
Status = PackRunStepExecutionStatus.Succeeded,
StatusReason = null,
LastTransitionAt = DateTimeOffset.UtcNow,
LastTransitionAt = timeProvider.GetUtcNow(),
NextAttemptAt = null
};
await AppendLogAsync(
@@ -317,7 +320,7 @@ public sealed class PackRunWorkerService : BackgroundService
{
Status = PackRunStepExecutionStatus.Skipped,
StatusReason = "unsupported-kind",
LastTransitionAt = DateTimeOffset.UtcNow
LastTransitionAt = timeProvider.GetUtcNow()
};
await AppendLogAsync(
executionContext.RunId,
@@ -339,7 +342,7 @@ public sealed class PackRunWorkerService : BackgroundService
ExecutionContext executionContext)
{
var record = executionContext.Steps[step.Id];
var now = DateTimeOffset.UtcNow;
var now = timeProvider.GetUtcNow();
var currentState = new PackRunStepState(record.Status, record.Attempts, record.LastTransitionAt, record.NextAttemptAt);
if (currentState.Status == PackRunStepExecutionStatus.Pending)
@@ -378,7 +381,7 @@ public sealed class PackRunWorkerService : BackgroundService
if (result.Succeeded)
{
currentState = PackRunStepStateMachine.CompleteSuccess(currentState, DateTimeOffset.UtcNow);
currentState = PackRunStepStateMachine.CompleteSuccess(currentState, timeProvider.GetUtcNow());
executionContext.Steps[step.Id] = record with
{
Status = currentState.Status,
@@ -410,7 +413,7 @@ public sealed class PackRunWorkerService : BackgroundService
step.Id,
result.Error ?? "unknown error");
var failure = PackRunStepStateMachine.RegisterFailure(currentState, DateTimeOffset.UtcNow, executionContext.FailurePolicy);
var failure = PackRunStepStateMachine.RegisterFailure(currentState, timeProvider.GetUtcNow(), executionContext.FailurePolicy);
var updatedRecord = record with
{
Status = failure.State.Status,
@@ -603,7 +606,7 @@ public sealed class PackRunWorkerService : BackgroundService
{
Status = PackRunStepExecutionStatus.Succeeded,
StatusReason = null,
LastTransitionAt = DateTimeOffset.UtcNow,
LastTransitionAt = timeProvider.GetUtcNow(),
NextAttemptAt = null
};
}
@@ -619,7 +622,7 @@ public sealed class PackRunWorkerService : BackgroundService
{
Status = PackRunStepExecutionStatus.Failed,
StatusReason = reason,
LastTransitionAt = DateTimeOffset.UtcNow
LastTransitionAt = timeProvider.GetUtcNow()
};
}
@@ -634,7 +637,7 @@ public sealed class PackRunWorkerService : BackgroundService
{
Status = PackRunStepExecutionStatus.Pending,
StatusReason = reason,
LastTransitionAt = DateTimeOffset.UtcNow
LastTransitionAt = timeProvider.GetUtcNow()
};
}