Fix stranded snapshot markers on publish failure#22518
Conversation
PR Reviewer Guide 🔍(Review updated until commit 5577c6f)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 5577c6f Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit a0f69b9
Suggestions up to commit 104557c
Suggestions up to commit a9a5f13
Suggestions up to commit 1cb6abd
Suggestions up to commit 99f35b1
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #22518 +/- ##
============================================
- Coverage 73.50% 73.45% -0.06%
+ Complexity 76507 76465 -42
============================================
Files 6104 6104
Lines 346618 346670 +52
Branches 49888 49895 +7
============================================
- Hits 254793 254641 -152
- Misses 71541 71796 +255
+ Partials 20284 20233 -51 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
shourya035
left a comment
There was a problem hiding this comment.
Please add some integration tests to ensure that the feature works end to end with induced cluster manager failures
99f35b1 to
1cb6abd
Compare
|
Persistent review updated to latest commit 1cb6abd |
|
❌ Gradle check result for 1cb6abd: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
1cb6abd to
a9a5f13
Compare
|
Persistent review updated to latest commit a9a5f13 |
a9a5f13 to
104557c
Compare
|
Persistent review updated to latest commit 104557c |
104557c to
a0f69b9
Compare
|
Persistent review updated to latest commit a0f69b9 |
Signed-off-by: Sukriti Sinha <sukriiti@amazon.com>
a0f69b9 to
5577c6f
Compare
|
Persistent review updated to latest commit 5577c6f |
|
|
||
| @Override | ||
| public ClusterState execute(ClusterState currentState) { | ||
| if (currentState.nodes().isLocalNodeElectedClusterManager() == false) { |
| final int nextAttempt = attempt + 1; | ||
| final TimeValue delay = computeBackoff(retryBackoff, attempt); | ||
| logger.info("Publish failed for [{}] (attempt {}), scheduling retry in [{}]", source, nextAttempt, delay); | ||
| threadPool.schedule(() -> clusterService.submitStateUpdateTask(source, taskFactory.get()), delay, ThreadPool.Names.GENERIC); |
There was a problem hiding this comment.
We should handle rejections from this block, otherwise this would throw unhandled exceptions
| * delay is clamped to a sane maximum in case maxRetries/retryBackoff are configured to large values. | ||
| */ | ||
| static TimeValue computeBackoff(TimeValue base, int attempt) { | ||
| final long delayMillis = Math.min(base.millis() * (1L << Math.min(attempt, 30)), TimeValue.timeValueDays(1).millis()); |
There was a problem hiding this comment.
We should add bounds to prevent this from going into negative values
| @@ -348,6 +349,11 @@ public SnapshotsService( | |||
| .addSettingsUpdateConsumer(MAX_CONCURRENT_SNAPSHOT_OPERATIONS_SETTING, i -> maxConcurrentOperations = i); | |||
| } | |||
|
|
|||
| maxRetries = SNAPSHOT_CLEANUP_RETRIES_SETTING.get(settings); | |||
There was a problem hiding this comment.
These settings should be applied on cluster manager nodes only, just like how we did for MAX_CONCURRENT_SNAPSHOT_OPERATIONS_SETTING
|
❌ Gradle check result for 5577c6f: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
| return new ClusterStateUpdateTask() { | ||
| @Override | ||
| public ClusterState execute(ClusterState currentState) { | ||
| if (currentState.nodes().isLocalNodeElectedClusterManager() == false) { |
There was a problem hiding this comment.
Same here, what is the motive behind having the cluster manager active check?
| }, 60, TimeUnit.SECONDS); | ||
|
|
||
| logger.info("--> verify no dangling markers block index operations"); | ||
| assertAcked(client().admin().indices().prepareDelete("test-idx").get()); |
There was a problem hiding this comment.
Can we also assert the state of the snapshot here?
| assertAcked(client().admin().indices().prepareDelete("test-idx").get()); | ||
| } | ||
|
|
||
| public void testSnapshotCompletesAfterClusterManagerFailoverDuringFinalization() throws Exception { |
There was a problem hiding this comment.
What is the difference between this test and testSnapshotMarkerCleanedUpAfterClusterManagerFailover?
| assertTrue(snapshotsInProgress.entries().isEmpty()); | ||
| } | ||
|
|
||
| public void testIndexDeletionUnblockedAfterSnapshotCleanup() throws Exception { |
There was a problem hiding this comment.
We can have this on the existing tests itself. We are deleting indices after every test, if the index deletion goes through, we should be able to assert the contents of this test
Description
Adds
retryOrFailOnClusterManagerFailOverhelper that retries a failed cluster-state publish (marker removal) with bounded exponential backoff (1s/2s/4s, max 3 retries) when the node is still the elected cluster-manager. Without this, a publish failure on a stable cluster-manager strands the in-progress snapshot marker forever, blocking index deletion and close.Also fixes a latent stale-read bug in
stateWithoutSnapshotV2: the innerexecute()was reading from the captured outerstateparameter instead of the livecurrentState, which could clobber concurrentcluster-state changes. The method is refactored into a task factory (
createStateWithoutSnapshotV2Task) that makes this bug structurally impossible to reintroduce.The retry behavior is gated behind the
SNAPSHOT_RESILIENCEfeature flag (default off). The stale-read fix is unconditional.Depends on #22516 (PR-C). Will rebase once that merges.
Testing
RetryOrFailOnClusterManagerFailOverTests: 10 unit tests covering helper decision logic, stale-state bug fix, and retried-task behavior.-Dtests.iters=20for seed stability.Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.