fix: Optimize cleanup jobs, eliminate raw ES client usage, add test coverage#2267
Open
niemyjski wants to merge 5 commits into
Open
fix: Optimize cleanup jobs, eliminate raw ES client usage, add test coverage#2267niemyjski wants to merge 5 commits into
niemyjski wants to merge 5 commits into
Conversation
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
commented
May 30, 2026
niemyjski
force-pushed
the
niemyjski/verbose-guacamole
branch
from
May 30, 2026 02:45
154223e to
7788c75
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR refactors cleanup jobs to rely on repository abstractions, improves duplicate stack cleanup behavior, and adds integration coverage for cleanup/repository operations.
Changes:
- Reworked orphaned-data and cleanup jobs with lock renewal, cancellation checks, and repository-based deletes/updates.
- Added event repository helpers for bulk deletion, stack reassignment, and distinct-id aggregation.
- Added integration tests for cleanup pagination, retention, duplicate signatures, and event repository operations.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/Exceptionless.Core/Jobs/CleanupDataJob.cs |
Extends lock duration and renews locks during paged cleanup/retention loops. |
src/Exceptionless.Core/Jobs/CleanupOrphanedDataJob.cs |
Replaces direct Elasticsearch calls with repository methods for orphan cleanup and duplicate-stack fixing. |
src/Exceptionless.Core/Repositories/EventRepository.cs |
Adds bulk delete, stack reassignment, and composite aggregation helpers. |
src/Exceptionless.Core/Repositories/Interfaces/IEventRepository.cs |
Exposes new event repository cleanup/query APIs and composite cursor type. |
src/Exceptionless.Core/Repositories/StackRepository.cs |
Adds duplicate signature aggregation lookup. |
src/Exceptionless.Core/Repositories/Interfaces/IStackRepository.cs |
Exposes duplicate signature lookup API. |
tests/Exceptionless.Tests/Jobs/CleanupDataJobTests.cs |
Adds cleanup pagination and retention integration coverage. |
tests/Exceptionless.Tests/Jobs/CleanupOrphanedDataJobTests.cs |
Adds integration coverage for orphan cleanup and duplicate stack merging. |
tests/Exceptionless.Tests/Repositories/EventRepositoryTests.cs |
Adds coverage for distinct ids, stack reassignment, and bulk delete helpers. |
tests/Exceptionless.Tests/Repositories/StackRepositoryTests.cs |
Adds duplicate signature repository coverage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
niemyjski
force-pushed
the
niemyjski/verbose-guacamole
branch
from
May 30, 2026 03:27
7788c75 to
3c5880b
Compare
Member
Author
|
Merged origin/main and addressed the outstanding review feedback in 92fa434. Summary:
Verification:
All review threads are resolved. |
niemyjski
force-pushed
the
niemyjski/verbose-guacamole
branch
from
July 10, 2026 12:39
92fa434 to
281071e
Compare
Member
Author
|
Production-readiness pass complete on f6fcc4b.
Production-readiness verdict: READY. |
…ction-readiness-20260715
Member
Author
|
Production-readiness refresh complete on bd560b0.
Production-readiness verdict: READY. PR remains open and unmerged. |
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.
Summary
Comprehensive optimization of cleanup jobs: eliminate direct Elasticsearch client usage from jobs, fix critical bugs, preserve cleanup correctness under concurrent ingestion, and add full integration test coverage.
Critical Bug Fixes
@min_count:2→@min:2inGetDuplicateSignaturesAsyncThe
@min_countsyntax is silently ignored by Foundatio Parsers, causing the aggregation to return ALL signature hashes (not just duplicates). This would have causedFixDuplicateStacksAsyncto treat every stack as a duplicate on the next run.FixDuplicateStacksAsynconly ran one batch (regression from refactor)The original code looped until
GetDuplicateSignaturesAsyncreturned empty. The refactor broke this. Restored the loop with:ImmediateConsistency()onCountAsyncinsideGetDuplicateSignaturesAsync(one refresh per batch, matching the originalIndices.RefreshAsynccall pattern — NOT per item)ReassignStackAsyncdata-loss hazard on empty sequenceIf
sourceStackIdswas empty,PatchAllAsyncwould have no stack filter and would reassign ALL events to the target stack. Added materialization + early return guard.FixDuplicateStacksAsyncevent-first orderingEvent reassignment completes before a duplicate stack is finalized as a redirect tombstone. If event reassignment fails, duplicate stacks remain visible and no data is lost.
GetDistinctFieldValuesAsynccursor correctnessDistinct event identifiers use composite aggregation pagination with an explicit next-value cursor so callers reliably detect the end of pagination.
Architecture (eliminate raw ES client from jobs)
CleanupOrphanedDataJobto use repository methods exclusivelyGetDistinctFieldValuesAsyncusing composite aggregation (encapsulated in the repository — composite aggregation is not in Foundatio's DSL, so raw client use is justified and documented)RemoveAllByProjectIdsAsync/RemoveAllByOrganizationIdsAsyncandRemoveAllByStackIdsAsynctoIEventRepositoryReassignStackAsyncusing a parameterized Painless script and strict post-write verificationGetDuplicateSignaturesAsynctoIStackRepositoryConcurrency and lossless reconciliation
Stackpersistence so stale full-document saves cannot overwrite cleanup mergesindex_not_found_exception; other shard/index verification failures fail closedOther Fixes
OperationCanceledExceptionhandling before the intentionally broad per-signature catchis_deleted:falsefilters where repository soft-delete filtering applies:{Message}to error log format stringsMerged onto current main
Merged the latest
origin/mainwith a normal merge commit and kept the final diff limited to the intended cleanup, repository, serialization, and test files.Test Coverage
Coverage includes: