Add retention sweep outcome tracking and reporting - #5916
Merged
Merged
Conversation
warwickschroeder
force-pushed
the
warwick/retention-purge-outcome
branch
from
September 23, 2026 05:14
d5e29b5 to
de03132
Compare
rbev
approved these changes
Sep 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
The manual retention purge status could not tell a purge that failed from one that worked: every pass swallowed its own error, and the finish time was stamped either way. This adds an outcome and an error to the status, and fixes three nearby ways a cancelled or finished sweep was misreported. It does not change what the sweep deletes, the hourly schedule, or the RavenDB 501 responses.
GET /api/maintenance/retention/purge/statusgainslast_outcome(succeeded,failed,cancelled) andlast_error, one"<Pass>: <first line of the message>"entry per failed pass. A cancelled run keeps the errors of passes that failed before it. The full error stays in the log. NewRetentionSweepOutcomeandRetentionPurgeOutcomeenums, mapped inRetentionApi.RetentionSweeperkeeps a single volatileRetentionSweepCurrentStatusthat is replaced whole, so a poll never mixes two runs. Starting a run clears the previous finish time and outcome. The status covers the hourly sweep as well as the manual one.cancelledin the metrics and the status, and the sweep stops there instead of running the later passes.SqlException, so the type-based filters recorded a shutdown as a failed pass and logged it as an error. The catches inRunPass,SweepBody, the manual path andExecuteAsyncnow go by the sweep's token. PS0019 is suppressed with that reason.Interlocked.CompareExchangeso a run that starts in that gap is not overwritten. A caller who seesis_running: falsefinds the lock free. A short wait inTryStartManualSweepwas rejected because it let a fast second sweep start instead of being refused.Tests
ServiceControl.Persistence.Tests/EFCore/RetentionSweepTests: outcome on success, failed passes (every error listed, first line only), cancellation before and during a query, cancellation between batches for failed messages and the event log, errors kept on cancel, the hourly path, and clearing at start. Two command interceptors drive the cancellation cases; the during-a-query test fails on SQL Server with the old filters.ServiceControl.UnitTests/Infrastructure/RetentionApiTests(new file): every outcome maps to the API enum of the same name, and the error passes through.ServiceControl.AcceptanceTests/WebApi/When_triggering_a_manual_retention_purge: a completed purge reportssucceededover HTTP.