Skip to content

Conversation

@superhx
Copy link
Collaborator

@superhx superhx commented Nov 14, 2025

cherry-pick #3010

@superhx superhx merged commit 17d3e5f into 1.6 Nov 14, 2025
9 of 10 checks passed
@superhx superhx deleted the cp_3010 branch November 14, 2025 09:30
Copilot finished reviewing on behalf of Gezi-lzq November 14, 2025 09:31
Copy link
Contributor

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 refactors queue time metric recording for network bandwidth limiting by moving it from call sites into the AsyncNetworkBandwidthLimiter class. This centralizes the metric collection logic and reduces code duplication.

  • Moved queue time metric recording from external call sites to inside AsyncNetworkBandwidthLimiter.BucketItem.complete()
  • Removed manual timer tracking code from AbstractObjectStorage and ElasticReplicaManager
  • Changed BucketItem from static to non-static inner class to access the limiter's type field

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
s3stream/src/main/java/com/automq/stream/s3/operator/AbstractObjectStorage.java Removed manual queue time metric recording and timer tracking for both inbound and outbound bandwidth limiting
s3stream/src/main/java/com/automq/stream/s3/network/AsyncNetworkBandwidthLimiter.java Added queue time metric recording to BucketItem.complete() and changed BucketItem to non-static inner class
s3stream/src/main/java/com/automq/stream/s3/metrics/stats/NetworkStats.java Refactored networkLimiterQueueTimeStats() with double-check pattern (though redundant)
core/src/main/scala/kafka/server/streamaspect/ElasticReplicaManager.scala Removed manual queue time metric recording from acquireNetworkOutPermit()

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

Comment on lines +99 to +111
HistogramMetric metric;
if (type == AsyncNetworkBandwidthLimiter.Type.INBOUND) {
metric = networkInboundLimiterQueueTimeStatsMap.get(strategy);
if (metric == null) {
metric = networkInboundLimiterQueueTimeStatsMap.computeIfAbsent(strategy, k -> S3StreamMetricsManager.buildNetworkInboundLimiterQueueTimeMetric(MetricsLevel.INFO, strategy));
}
} else {
metric = networkOutboundLimiterQueueTimeStatsMap.get(strategy);
if (metric == null) {
metric = networkOutboundLimiterQueueTimeStatsMap.computeIfAbsent(strategy, k -> S3StreamMetricsManager.buildNetworkOutboundLimiterQueueTimeMetric(MetricsLevel.INFO, strategy));
}
}
return metric;
Copy link

Copilot AI Nov 14, 2025

Choose a reason for hiding this comment

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

The double-check pattern here is redundant. computeIfAbsent() already handles the null case atomically and will only compute the value if the key is absent. The explicit null check before calling computeIfAbsent() provides no additional benefit and adds unnecessary complexity.

Consider simplifying to:

public HistogramMetric networkLimiterQueueTimeStats(AsyncNetworkBandwidthLimiter.Type type, ThrottleStrategy strategy) {
    return type == AsyncNetworkBandwidthLimiter.Type.INBOUND
            ? networkInboundLimiterQueueTimeStatsMap.computeIfAbsent(strategy, k -> S3StreamMetricsManager.buildNetworkInboundLimiterQueueTimeMetric(MetricsLevel.INFO, strategy))
            : networkOutboundLimiterQueueTimeStatsMap.computeIfAbsent(strategy, k -> S3StreamMetricsManager.buildNetworkOutboundLimiterQueueTimeMetric(MetricsLevel.INFO, strategy));
}
Suggested change
HistogramMetric metric;
if (type == AsyncNetworkBandwidthLimiter.Type.INBOUND) {
metric = networkInboundLimiterQueueTimeStatsMap.get(strategy);
if (metric == null) {
metric = networkInboundLimiterQueueTimeStatsMap.computeIfAbsent(strategy, k -> S3StreamMetricsManager.buildNetworkInboundLimiterQueueTimeMetric(MetricsLevel.INFO, strategy));
}
} else {
metric = networkOutboundLimiterQueueTimeStatsMap.get(strategy);
if (metric == null) {
metric = networkOutboundLimiterQueueTimeStatsMap.computeIfAbsent(strategy, k -> S3StreamMetricsManager.buildNetworkOutboundLimiterQueueTimeMetric(MetricsLevel.INFO, strategy));
}
}
return metric;
return type == AsyncNetworkBandwidthLimiter.Type.INBOUND
? networkInboundLimiterQueueTimeStatsMap.computeIfAbsent(strategy, k -> S3StreamMetricsManager.buildNetworkInboundLimiterQueueTimeMetric(MetricsLevel.INFO, strategy))
: networkOutboundLimiterQueueTimeStatsMap.computeIfAbsent(strategy, k -> S3StreamMetricsManager.buildNetworkOutboundLimiterQueueTimeMetric(MetricsLevel.INFO, strategy));

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.

3 participants