Skip to content

Conversation

@lluwm
Copy link
Contributor

@lluwm lluwm commented Nov 17, 2025

Problem Statement

Heartbeat messages in Venice were including Venice Transport Protocol (VTP) headers unnecessarily, adding overhead to frequent heartbeat communications. Since heartbeats are primarily for liveness detection rather than data transport, this overhead was wasteful.

Solution

Implemented an optimization to conditionally exclude VTP headers from heartbeat messages when Venice's robust schema evolution infrastructure is available to handle compatibility.

When dependent features are enabled, heartbeat messages skip VTP headers because:

  • KME Schema Registration: Servers register schemas during startup via ControllerClientBackedSystemSchemaInitializer
  • Schema Reader: RouterBackedSchemaReader automatically fetches unknown schemas from system store
  • Graceful Handling: InternalAvroSpecificSerializer handles unknown protocol versions via schema reader

Testing

  • Updated existing tests to maintain compatibility
  • Add new integration test to validate that optimization works correctly with Venice's KME schema evolution infrastructure (TestServerKMERegistrationFromMessageHeader.java)

Code changes

  • Added new code behind a config. If so list the config names and their default values in the PR description.
  • Introduced new log lines.
    • Confirmed if logs need to be rate limited to avoid excessive logging.

Concurrency-Specific Checks

Both reviewer and PR author to verify

  • Code has no race conditions or thread safety issues.
  • Proper synchronization mechanisms (e.g., synchronized, RWLock) are used where needed.
  • No blocking calls inside critical sections that could lead to deadlocks or performance degradation.
  • Verified thread-safe collections are used (e.g., ConcurrentHashMap, CopyOnWriteArrayList).
  • Validated proper exception handling in multi-threaded code to avoid silent thread termination.

How was this PR tested?

  • New unit tests added.
  • New integration tests added.
  • Modified or extended existing tests.
  • Verified backward compatibility (if applicable).

Does this PR introduce any user-facing or breaking changes?

  • No. You can skip the rest of this section.
  • Yes. Clearly explain the behavior change and its impact.

… Headers

Problem Statement
Heartbeat messages in Venice were including Venice Transport Protocol (VTP) headers unnecessarily,
adding overhead to frequent heartbeat communications.
Since heartbeats are primarily for liveness detection rather than data transport, this overhead was wasteful.

Solution
Implemented an optimization to conditionally exclude VTP headers from heartbeat messages when Venice's
robust schema evolution infrastructure is available to handle compatibility.

When dependent features are enabled, heartbeat messages skip VTP headers because:
- KME Schema Registration: Servers register schemas during startup via ControllerClientBackedSystemSchemaInitializer
- Schema Reader: RouterBackedSchemaReader automatically fetches unknown schemas from system store
- Graceful Handling: InternalAvroSpecificSerializer handles unknown protocol versions via schema reader

Testing
- Updated existing tests to maintain compatibility
- Add new integration test to validate that optimization works correctly with Venice's KME schema evolution infrastructure
  (TestServerKMERegistrationFromMessageHeader.java)
Copilot AI review requested due to automatic review settings November 17, 2025 21:25
Copilot finished reviewing on behalf of lluwm November 17, 2025 21:26
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR optimizes heartbeat messages in Venice by conditionally excluding Venice Transport Protocol (VTP) headers when the system's schema evolution infrastructure can handle compatibility. The optimization reduces overhead for frequent heartbeat communications while maintaining schema evolution capabilities through KME schema registration and RouterBackedSchemaReader.

Key changes:

  • Added logic to conditionally skip VTP headers in heartbeat messages based on dependent feature flags
  • Updated VeniceWriter to accept a new parameter controlling VTP header inclusion
  • Extended test coverage with new integration tests and updated existing mocks

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
VeniceWriter.java Refactored header logic to conditionally add VTP headers based on message type and feature flags
StoreIngestionTask.java Added storage for system schema initialization flag
LeaderFollowerStoreIngestionTask.java Integrated dependent feature check before sending heartbeats
KafkaStoreIngestionService.java Added method to check KME schema reader presence and improved logging
HeartbeatMonitoringService.java Added getter for KafkaStoreIngestionService
VeniceWriterUnitTest.java Updated test to cover VTP header skip logic with additional test parameters
VeniceWriterHeartbeatHeaderTest.java New test file validating VTP header behavior for heartbeats vs data messages
TestServerKMERegistrationFromMessageHeader.java Added integration test for heartbeat optimization and refactored common setup
MaterializedViewWriterTest.java Updated mocks to include new heartbeat parameter
StoreIngestionTaskTest.java Updated mocks to include new heartbeat parameter
LeaderFollowerStoreIngestionTaskTest.java Added comprehensive test for dependent feature flag combinations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

*
* Server 1 deploys -> Registers KME v2 in system store during startup. (requires isSystemSchemaInitializationAtStartTimeEnabled = true)
* Server 1 sends heartbeat -> Serialized with KME v2 (no VTP header)
* Server 2 receives heartbeat -> Detects unknown protocol version, schema reader fetches KME v2. (requires KME scheme reader to be present)
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'scheme' to 'schema' in comment.

Suggested change
* Server 2 receives heartbeat -> Detects unknown protocol version, schema reader fetches KME v2. (requires KME scheme reader to be present)
* Server 2 receives heartbeat -> Detects unknown protocol version, schema reader fetches KME v2. (requires KME schema reader to be present)

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings November 18, 2025 18:32
Copilot finished reviewing on behalf of lluwm November 18, 2025 18:34
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

for (int i = 0; i < 10; i++) {
veniceWriter.sendHeartbeat(
topicPartition,
null, // No callback needed for this test
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Passing null for the callback is acceptable here, but it would be more explicit to use a mock callback or a no-op callback to better demonstrate intent and avoid potential NPE issues if the implementation changes.

Suggested change
null, // No callback needed for this test
(metadata, exception) -> {}, // No-op callback for clarity and safety

Copilot uses AI. Check for mistakes.
leaderCompleteState,
originTimeStampMs);
}

Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Changing the visibility of 'sendIngestionHeartbeat' from private to package-private for testing purposes is acceptable, but consider adding a comment explaining that this is intentionally package-private for test access to make the design decision explicit.

Suggested change
/**
* Package-private for test access. This method's visibility is intentionally not private
* to allow unit tests in the same package to invoke it.
*/

Copilot uses AI. Check for mistakes.
Comment on lines +424 to +429
kafkaMessageEnvelopeSchemaReader.ifPresent(reader -> {
LOGGER.info(
"Initialized KME schema reader. Type: {}, Latest value schema ID: {}",
reader.getClass().getSimpleName(),
reader.getLatestValueSchemaId());
kafkaValueSerializer.setSchemaReader(reader);
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The log message at INFO level is logged every time the service initializes. Consider whether this should be rate-limited or moved to DEBUG level to avoid log pollution in environments with frequent restarts, or ensure it's only logged once during service lifetime.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant