Skip to content

fix(aws/ladder): scope RI utilization query to EC2+region for reshape decisions (follow-up to #1361) - #1479

Merged
cristim merged 2 commits into
mainfrom
fix/1361-ce-utilization-filter
Jul 22, 2026
Merged

fix(aws/ladder): scope RI utilization query to EC2+region for reshape decisions (follow-up to #1361)#1479
cristim merged 2 commits into
mainfrom
fix/1361-ce-utilization-filter

Conversation

@cristim

@cristim cristim commented Jul 21, 2026

Copy link
Copy Markdown
Member

Summary

  • GetRIUtilization (providers/aws/recommendations/utilization.go) built GetReservationUtilizationInput with no Filter at all, grouping only by SUBSCRIPTION_ID. This blends utilization across every reserved-resource type in the account (RDS, ElastiCache, OpenSearch, Redshift, standard EC2 RIs) and every region into a single number.
  • The ladder ConvertibleRI (buffer) layer (providers/aws/ladder/layer_states.go) reads this as "this account/region's EC2 convertible-RI utilization" and uses it to decide whether to trigger a real RI reshape/exchange (pkg/ladder/allocate.go, ActionReshape). An underutilized RI in an unrelated service or region could trigger a reshape, or a genuinely poorly-utilized convertible RI could be masked by healthy unrelated reservations blended into the same aggregate. Real-money-decision correctness bug, follow-up to feat(ladder): integrate stranded phase-2 AWS capability onto main #1361 (merged).
  • Fix: add a Filter scoping SERVICE=Amazon Elastic Compute Cloud - Compute and REGION=<region> to the CE call (mirrors the existing serviceRegionFilter pattern in coverage.go). Threaded a region parameter through GetRIUtilization and its callers.
  • Also intersect the (now EC2+region-scoped) response against the account's own convertible RI IDs (ListConvertibleReservedInstances) before aggregating in GetLayerStates, since a standard (non-convertible) EC2 RI in the same account/region would otherwise still pass the SERVICE+REGION filter and blend into the layer's UtilizationPct. This was a clean, contained addition since GetLayerStates already has both the RI list and the utilization slice in scope, so it's included rather than deferred as a follow-up.

Test plan

  • go build ./... -- exit 0
  • go vet ./... -- exit 0
  • go test ./providers/aws/... ./internal/api/... ./internal/server/... -- exit 0
  • go test ./... (full suite) -- exit 0
  • New regression tests added: TestGetRIUtilization_ScopesToEC2AndRegion, TestGetRIUtilization_EmptyRegionOmitsRegionFilter (providers/aws/recommendations/utilization_test.go), TestGetLayerStates_RILayer_UtilizationExcludesUnrelatedReservations (providers/aws/ladder/ladder_test.go) -- all confirmed to FAIL against the pre-fix code (verified manually by reverting the fix locally) and PASS after
  • golangci-lint run on touched packages -- 0 new issues introduced by this diff (pre-existing repo debt in touched files left untouched, out of scope); note the CI-pinned v2.10.1 binary could not be installed in this sandbox (external-script-execution policy), so this was verified with the locally available v2.11.4 instead
  • gocyclo -over 10 on touched files -- exit 0, no output

Out of scope / documented follow-up

  • The MEDIUM finding in computeEC2CoveragePct (layer_states.go) -- the one-colon pool-key heuristic also matches ElastiCache/OpenSearch/Redshift/MemoryDB pool keys, not just EC2 -- was not fixed here. No engine decision currently consumes CoveragePct (confirmed by an earlier review), so today's impact is a wrong reported metric only, not a money-affecting decision. Filing as a separate follow-up issue.

@cristim cristim added triaged Item has been triaged priority/p1 Next up; this sprint severity/high Significant harm urgency/now Drop other things impact/many Affects most users effort/m Days type/bug Defect labels Jul 21, 2026
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 8 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: edae349b-6366-4d47-ac48-341b3131fded

📥 Commits

Reviewing files that changed from the base of the PR and between 1cc33d3 and b60f2a9.

📒 Files selected for processing (11)
  • internal/api/handler_ri_exchange.go
  • internal/api/handler_ri_exchange_integration_test.go
  • internal/api/handler_ri_exchange_test.go
  • internal/server/handler_ri_exchange.go
  • internal/server/ladder_write.go
  • providers/aws/ladder/interfaces.go
  • providers/aws/ladder/ladder_test.go
  • providers/aws/ladder/layer_states.go
  • providers/aws/recommendations/utilization.go
  • providers/aws/recommendations/utilization_test.go
  • providers/aws/service_client.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/1361-ce-utilization-filter

Comment @coderabbitai help to get the list of available commands.

@cristim

cristim commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

Filed the deferred computeEC2CoveragePct finding as a separate follow-up: #1482 (lower priority -- no engine decision currently consumes CoveragePct, so it's a wrong reported metric only, not a live money-affecting decision like the fix in this PR).

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@cristim Thanks for tracking the deferred computeEC2CoveragePct concern in #1482. I’ll review the PR with the EC2/region utilization scoping and convertible-RI filtering changes as the focus.


✏️ Learnings added
Learnt from: cristim
URL: https://github.com/LeanerCloud/CUDly/pull/1479

Timestamp: 2026-07-21T19:59:45.581Z
Learning: In `providers/aws/ladder/layer_states.go`, `computeEC2CoveragePct` uses a one-colon pool-key heuristic that can also match ElastiCache, OpenSearch, Redshift, and MemoryDB pool keys. As of PR `#1479`, no ladder engine decision consumes `CoveragePct`, so this is a reporting-metric correctness issue rather than a live money-affecting decision; it is tracked separately in GitHub issue `#1482`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

cristim added 2 commits July 22, 2026 23:27
… decisions

GetRIUtilization built GetReservationUtilization with no Filter at all,
so it blended utilization across every reserved-resource type in the
account (RDS, ElastiCache, OpenSearch, Redshift, standard EC2 RIs) and
every region into one SUBSCRIPTION_ID-grouped number. The ladder
ConvertibleRI (buffer) layer reads this as if it were EC2-convertible
utilization for one account/region, then uses it to decide whether to
trigger a real RI reshape/exchange -- an underutilized RI in an
unrelated service or region could trigger a reshape, or mask a
genuinely poorly-utilized convertible RI.

Add a SERVICE+REGION Filter to the CE call, mirroring the same pattern
already used by GetRICoverageMap in coverage.go. Also intersect the
(now EC2+region-scoped) response against the account's own convertible
RI IDs before aggregating in GetLayerStates, since a standard
(non-convertible) EC2 RI in the same account/region would otherwise
still pass the SERVICE+REGION filter and blend into the layer's
UtilizationPct.

Threads a region parameter through GetRIUtilization's callers
(providers/aws/ladder, providers/aws/service_client.go,
internal/server, internal/api). Follow-up to #1361.
The prior commit's code comments cited "#1461" as the tracking issue
for the RI utilization filter bug. #1461 is an unrelated PR (NaN/Inf
rejection in SP money parsing). The bug this fix addresses was
introduced by PR #1361, per the review that surfaced it; correct all
comment references accordingly.
@cristim
cristim force-pushed the fix/1361-ce-utilization-filter branch from d4a8a6a to b60f2a9 Compare July 22, 2026 21:33
@cristim

cristim commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim
cristim merged commit ae7b61b into main Jul 22, 2026
19 checks passed
@cristim
cristim deleted the fix/1361-ce-utilization-filter branch July 27, 2026 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/m Days impact/many Affects most users priority/p1 Next up; this sprint severity/high Significant harm triaged Item has been triaged type/bug Defect urgency/now Drop other things

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant