-
Notifications
You must be signed in to change notification settings - Fork 113
[controller] Skip truncating parent VT based on ConcurrentPushDetectionStrategy in the DeferredVersionSwapService #2355
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -13,6 +13,7 @@ | |||||
| import com.linkedin.venice.exceptions.VeniceNoClusterException; | ||||||
| import com.linkedin.venice.hooks.StoreLifecycleHooks; | ||||||
| import com.linkedin.venice.hooks.StoreVersionLifecycleEventOutcome; | ||||||
| import com.linkedin.venice.meta.ConcurrentPushDetectionStrategy; | ||||||
| import com.linkedin.venice.meta.LifecycleHooksRecord; | ||||||
| import com.linkedin.venice.meta.ReadWriteStoreRepository; | ||||||
| import com.linkedin.venice.meta.Store; | ||||||
|
|
@@ -1225,7 +1226,10 @@ public void updateStore(String clusterName, String storeName, VersionStatus stat | |||||
| // For jobs that stop polling early or for pushes that don't poll (empty push), we need to truncate the parent | ||||||
| // VT here to unblock the next push | ||||||
| String kafkaTopicName = Version.composeKafkaTopic(storeName, targetVersionNum); | ||||||
| if (!veniceParentHelixAdmin.isTopicTruncated(kafkaTopicName)) { | ||||||
| ConcurrentPushDetectionStrategy strategy = | ||||||
| veniceControllerMultiClusterConfig.getControllerConfig(clusterName).getConcurrentPushDetectionStrategy(); | ||||||
| // skip truncating if the topic was not created based on ConcurrentPushDetectionStrategy | ||||||
| if (strategy.isTopicWriteNeeded() && !veniceParentHelixAdmin.isTopicTruncated(kafkaTopicName)) { | ||||||
| LOGGER.info("Truncating parent VT for {}", kafkaTopicName); | ||||||
| veniceParentHelixAdmin.truncateKafkaTopic(Version.composeKafkaTopic(storeName, targetVersionNum)); | ||||||
|
||||||
| veniceParentHelixAdmin.truncateKafkaTopic(Version.composeKafkaTopic(storeName, targetVersionNum)); | |
| veniceParentHelixAdmin.truncateKafkaTopic(kafkaTopicName); |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -18,6 +18,7 @@ | |||||
| import com.linkedin.venice.controllerapi.StoreResponse; | ||||||
| import com.linkedin.venice.exceptions.VeniceException; | ||||||
| import com.linkedin.venice.hooks.StoreVersionLifecycleEventOutcome; | ||||||
| import com.linkedin.venice.meta.ConcurrentPushDetectionStrategy; | ||||||
| import com.linkedin.venice.meta.LifecycleHooksRecord; | ||||||
| import com.linkedin.venice.meta.LifecycleHooksRecordImpl; | ||||||
| import com.linkedin.venice.meta.ReadWriteStoreRepository; | ||||||
|
|
@@ -417,7 +418,9 @@ public void testSequentialRolloutFailurePath() throws Exception { | |||||
|
|
||||||
| // Simulate failure on region2 rollout by making rollForwardToFutureVersion throw an exception when region2 appears | ||||||
| doThrow(new VeniceException()).when(admin).rollForwardToFutureVersion(clusterName, storeName, region2); | ||||||
|
|
||||||
| doReturn(clusterConfig).when(veniceControllerMultiClusterConfig).getControllerConfig(clusterName); | ||||||
| doReturn(ConcurrentPushDetectionStrategy.PARENT_VERSION_STATUS_ONLY).when(clusterConfig) | ||||||
| .getConcurrentPushDetectionStrategy(); | ||||||
| // Create service | ||||||
| DeferredVersionSwapService deferredVersionSwapService = | ||||||
| new DeferredVersionSwapService(admin, veniceControllerMultiClusterConfig, stats, metricsRepository); | ||||||
|
|
@@ -430,6 +433,7 @@ public void testSequentialRolloutFailurePath() throws Exception { | |||||
| // Verify error recording was called due to the failure | ||||||
| verify(store, atLeastOnce()).updateVersionStatus(2, VersionStatus.PARTIALLY_ONLINE); | ||||||
| verify(admin, never()).rollForwardToFutureVersion(clusterName, storeName, region3); | ||||||
| verify(admin, never()).truncateKafkaTopic(anyString(), anyInt()); | ||||||
|
||||||
| verify(admin, never()).truncateKafkaTopic(anyString(), anyInt()); | |
| verify(admin, never()).truncateKafkaTopic(anyString()); |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test sets ConcurrentPushDetectionStrategy to TOPIC_BASED_ONLY (line 603) and mocks isTopicTruncated to return false (line 604), which according to the code logic in DeferredVersionSwapService.java line 1232 would trigger truncation (since isTopicWriteNeeded() returns true for TOPIC_BASED_ONLY and the topic is not truncated). However, line 616 expects that truncateKafkaTopic is never called. This test may not be properly validating the intended behavior. Consider either changing the strategy to PARENT_VERSION_STATUS_ONLY if the intent is to test that truncation doesn't happen, or adjusting the expectation to verify that truncation does happen with TOPIC_BASED_ONLY strategy.
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The verify call is checking for the wrong method signature. The actual code in DeferredVersionSwapService.java line 1234 calls truncateKafkaTopic(String topicName) with one parameter, but this test is verifying the two-parameter overload truncateKafkaTopic(anyString(), anyInt()). This means the test would not detect if the one-parameter version is called. Change this to verify(admin, never()).truncateKafkaTopic(anyString()); to match the actual method being called.
| verify(admin, never()).truncateKafkaTopic(anyString(), anyInt()); | |
| verify(admin, never()).truncateKafkaTopic(anyString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment could be more precise. It currently says "skip truncating if the topic was not created" but the logic checks if
isTopicWriteNeeded()returns true. Consider revising to: "skip truncating if the topic was not created (when strategy doesn't require topic writes)" to better explain the relationship between the strategy and topic creation.