Skip to content

Conversation

@arunkumarucet
Copy link
Contributor

Overview

This PR introduces a storage quota check for each segment during batch segment upload in PinotSegmentUploadDownloadRestletResource. The change ensures that every segment in a batch is validated against the table's storage quota before being committed.

Motivation

Previously, batch uploads did not enforce storage quota checks, which lead to quota violations. This change aligns batch upload behavior similar to single segment uploads, improving quota enforcement and cluster stability.

Implementation

Added a call to SegmentValidationUtils.checkStorageQuota() for each segment in the batch upload loop. If any segment fails the quota check, a ControllerApplicationException is thrown, aborting the batch operation. No segments are committed if any segment fails validation; the operation is atomic at the batch level. Temporary files for all processed segments are cleaned up in the finally block, ensuring no resource leaks.

@xiangfu0 xiangfu0 requested a review from Copilot January 15, 2026 08:48
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 adds storage quota validation to the batch segment upload process to prevent quota violations during bulk operations. Previously, only single segment uploads enforced quota checks, creating an inconsistency that could destabilize the cluster.

Changes:

  • Added storage quota validation for each segment in batch uploads
  • Reused tarred segment size as an approximation for untarred size (matching existing single upload behavior)
  • Maintained atomic batch operation semantics where quota failure aborts the entire batch

@codecov-commenter
Copy link

codecov-commenter commented Jan 15, 2026

Codecov Report

❌ Patch coverage is 0% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.18%. Comparing base (59dd212) to head (5f25a18).

Files with missing lines Patch % Lines
...ces/PinotSegmentUploadDownloadRestletResource.java 0.00% 7 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master   #17512      +/-   ##
============================================
+ Coverage     63.17%   63.18%   +0.01%     
+ Complexity     1477     1476       -1     
============================================
  Files          3172     3172              
  Lines        189751   189758       +7     
  Branches      29036    29037       +1     
============================================
+ Hits         119875   119901      +26     
+ Misses        60572    60548      -24     
- Partials       9304     9309       +5     
Flag Coverage Δ
custom-integration1 100.00% <ø> (ø)
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (ø)
java-11 63.14% <0.00%> (+<0.01%) ⬆️
java-21 63.14% <0.00%> (-0.01%) ⬇️
temurin 63.18% <0.00%> (+0.01%) ⬆️
unittests 63.18% <0.00%> (+0.01%) ⬆️
unittests1 55.50% <ø> (-0.04%) ⬇️
unittests2 34.05% <0.00%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

long segmentSizeInBytes = getSegmentSizeFromFile(sourceDownloadURIStr);
// Adding Storage Quota Check
long untarredSegmentSizeInBytes = segmentSizeInBytes;
SegmentValidationUtils.checkStorageQuota(segmentName, segmentSizeInBytes, untarredSegmentSizeInBytes,
Copy link
Contributor

Choose a reason for hiding this comment

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

checkStorageQuota will throw ControllerApplicationException with Response.Status.FORBIDDEN but will be caught by this method and re-throw as a INTERNAL_SERVER_ERROR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed. Now the uploadSegments method catches WebApplicationException first and re-throws it directly, preserving the original HTTP status code (403 FORBIDDEN for quota violations). This matches the pattern used in the single segment uploadSegment method.

} catch (Exception e) {
_controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_SEGMENT_UPLOAD_ERROR,
segmentUploadMetadataList.size());
_controllerMetrics.addMeteredTableValue(tableName, ControllerMeter.CONTROLLER_TABLE_SEGMENT_UPLOAD_ERROR, 1L);
Copy link
Contributor

Choose a reason for hiding this comment

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

We should bump up the metrics by segmentUploadMetadataList.size()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

// TODO: Include the un-tarred segment size when using the METADATA push rest API. Currently we can only use the
// tarred segment size as an approximation. Additionally, add the storage quota check for batch upload mode.
// tarred segment size as an approximation.
long segmentSizeInBytes = getSegmentSizeFromFile(sourceDownloadURIStr);
Copy link
Contributor

Choose a reason for hiding this comment

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

We should also check if it is positive

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed. Applied same logic used in uploadSegment() method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants