Skip to content

Commit 660cd9b

Browse files
committed
Guard native saga controls with their canonical deadline
Bound each healthy control job by its own persisted deadline and the configured hold delay. Preserve deliberate early stale-job rejection and all durable-job authorization, revision and completion assertions. Current full Release solution build: 0 warnings, 0 errors. Canonical whole-solution formatter and governance passed. Full Aspire unit v3 is running after runtime-option repairs; prior unit v1 failed186 cases and v2 was aborted by an AppHost stop request. Runtime, scalar, recovery, RF3, source-bound coverage and exact-source Linux qualification remain open.
1 parent a9e104a commit 660cd9b

2 files changed

Lines changed: 16 additions & 9 deletions

File tree

‎docs/implementation/status.json‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4873,20 +4873,20 @@
48734873
"status": "in_progress",
48744874
"feature": "docs/Features/CodeQuality.md",
48754875
"decision": "docs/ADR/ADR-113-centralized-runtime-options.md",
4876-
"sourceStage": "runtime_policy_migration_runtime_failures_under_repair_final_canonical_refresh_pending",
4877-
"canonicalBuildPassed": false,
4876+
"sourceStage": "runtime_repairs_complete_canonical_release_and_format_v5_passed_full_Aspire_unit_v3_running",
4877+
"canonicalBuildPassed": true,
48784878
"runtimeQualified": false,
48794879
"fullTaskComplete": false,
48804880
"remaining": [
48814881
"Pass full Aspire-owned unit/scalar/recovery and native RF3 execution, retaining original reports",
48824882
"Pass required source-bound coverage and delivered-source Linux qualification",
48834883
"Review any actual runtime failures without weakening diagnostics, contracts or assertions"
48844884
],
4885-
"canonicalFormatterPassed": false,
4885+
"canonicalFormatterPassed": true,
48864886
"developmentEvidence": {
48874887
"directory": "artifacts/code-quality/general-runtime-options-development-20261006",
4888-
"canonicalRelease": "keyload-general-options-full-release-v4.log",
4889-
"canonicalFormat": "keyload-general-options-canonical-format-v3.log",
4888+
"canonicalRelease": "keyload-general-options-full-release-v5.log",
4889+
"canonicalFormat": "keyload-general-options-canonical-format-v5.log",
48904890
"analyzers": {
48914891
"suite": "analyzers",
48924892
"passed": 340,

‎tests/KeyLoad.UnitTests/Features/Messaging/Cases/NativeSagaTimeoutFunctionalTests.cs‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public async Task NativeJobObservesCompletionCommittedAfterScheduling()
4242
NativeSagaTimeoutTestData.CompleteSaga(fixture, stale);
4343

4444
var control = NativeSagaTimeoutTestData.CreateWaitingSaga(fixture, SagaPrincipalId);
45-
var controlDueAt = staleJobDueAt.Add(fixture.TestProfile.HeldJobDelay);
45+
var controlDueAt = ControlJobDueAt(staleJobDueAt, control);
4646
await fixture.JobHarness.ScheduleAsync(control.Hint, controlDueAt, CancellationToken.None);
4747
var controlShards = await fixture.JobHarness.CaptureOwnedShardsAsync(controlDueAt, CancellationToken.None);
4848
await Assert.That(await NativeSagaTimeoutJobHarness.CountScheduledJobsAsync(controlShards)).IsGreaterThan(NoScheduledJobs);
@@ -68,7 +68,7 @@ public async Task NativeJobObservesSagaCancellationBeforeTimeout()
6868
NativeSagaTimeoutTestData.CancelSaga(fixture, stale);
6969

7070
var control = NativeSagaTimeoutTestData.CreateWaitingSaga(fixture, SagaPrincipalId);
71-
var controlDueAt = staleJobDueAt.Add(fixture.TestProfile.HeldJobDelay);
71+
var controlDueAt = ControlJobDueAt(staleJobDueAt, control);
7272
await fixture.JobHarness.ScheduleAsync(control.Hint, controlDueAt, CancellationToken.None);
7373
var controlShards = await fixture.JobHarness.CaptureOwnedShardsAsync(controlDueAt, CancellationToken.None);
7474
await Assert.That(await NativeSagaTimeoutJobHarness.CountScheduledJobsAsync(controlShards)).IsGreaterThan(NoScheduledJobs);
@@ -95,7 +95,7 @@ public async Task NativeJobObservesPersistedCreatorRevocationBeforeTimeout()
9595
NativeSagaTimeoutTestData.RevokeCreator(fixture);
9696

9797
var control = NativeSagaTimeoutTestData.CreateWaitingSaga(fixture, SagaPrincipalId);
98-
var controlDueAt = staleJobDueAt.Add(fixture.TestProfile.HeldJobDelay);
98+
var controlDueAt = ControlJobDueAt(staleJobDueAt, control);
9999
await fixture.JobHarness.ScheduleAsync(control.Hint, controlDueAt, CancellationToken.None);
100100
var controlShards = await fixture.JobHarness.CaptureOwnedShardsAsync(controlDueAt, CancellationToken.None);
101101
await Assert.That(await NativeSagaTimeoutJobHarness.CountScheduledJobsAsync(controlShards)).IsGreaterThan(NoScheduledJobs);
@@ -120,7 +120,7 @@ public async Task NativeJobObservesFutureCanonicalDeadlineBeforeTimeout()
120120
await Assert.That(await NativeSagaTimeoutJobHarness.CountScheduledJobsAsync(staleShards)).IsGreaterThan(NoScheduledJobs);
121121

122122
var control = NativeSagaTimeoutTestData.CreateWaitingSaga(fixture, SagaPrincipalId);
123-
var controlDueAt = staleJobDueAt.Add(fixture.TestProfile.HeldJobDelay);
123+
var controlDueAt = ControlJobDueAt(staleJobDueAt, control);
124124
await fixture.JobHarness.ScheduleAsync(control.Hint, controlDueAt, CancellationToken.None);
125125
var controlShards = await fixture.JobHarness.CaptureOwnedShardsAsync(controlDueAt, CancellationToken.None);
126126
await Assert.That(await NativeSagaTimeoutJobHarness.CountScheduledJobsAsync(controlShards)).IsGreaterThan(NoScheduledJobs);
@@ -135,6 +135,13 @@ await Assert.That(fixture.Database.Database.InspectMessage(SagaPrincipalId, futu
135135
NativeSagaTimeoutTestData.TimeoutMessageId(future.Id, RevisionOne))).IsNull();
136136
}
137137

138+
private DateTimeOffset ControlJobDueAt(DateTimeOffset previousJobDueAt, NativeSagaTimeoutCase control)
139+
{
140+
var plannedDueAt = previousJobDueAt.Add(fixture.TestProfile.HeldJobDelay);
141+
var canonicalDueAt = control.Deadline.Add(fixture.TestProfile.HeldJobDelay);
142+
return plannedDueAt >= canonicalDueAt ? plannedDueAt : canonicalDueAt;
143+
}
144+
138145
private async Task<SagaInspection> WaitForTimedOutSagaAsync(QueueLaneRef lane, Guid sagaId)
139146
{
140147
using var deadline = new CancellationTokenSource(fixture.TestProfile.CompletionTimeout);

0 commit comments

Comments
 (0)