Repository navigation
fix(purchase): pass RequestedAt so Redshift reserved-node buys work with the new dedupe - #1138
Conversation
…s.RequestedAt Redshift purchases with an idempotency token now require RequestedAt to bound the DescribeReservedNodes dedupe window. Only pkg and providers/aws move; azure and gcp keep their pin. Must ship with the execution.go change that sets RequestedAt, or tokenized Redshift buys refuse. Part of #702 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
go's Redshift purchase dedupe bounds its DescribeReservedNodes match window with PurchaseOptions.RequestedAt and refuses a tokenized buy without it. Set it to the UTC dispatch time immediately before the single PurchaseCommitment call, for all providers (others ignore it). Tests cover a two-account fan-out for EC2 and Redshift and the empty-token path. Part of #702 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
go's Redshift match window (start >= RequestedAt-5min) has no upper bound, so a same-tuple purchase shortly after a completed one adopts the earlier node without buying, and an unknown outcome followed by a new same-tuple purchase outside the window can double-buy. Redshift re-drive stays refused. Part of #702 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reached
This review includes 5 billable files and costs up to $1.25.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Or wait 25 minutes for your next included review. View limit details
Comment |
…doption Review of the RequestedAt change found three gaps worth tracking: same-tuple purchases in parallel or sequence are matched by tuple only, adoption of an existing node is recorded as an ordinary purchase, and RequestedAt is stamped per dispatch rather than per lineage (safe only while re-drive is refused). Part of #702 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge gate at
|
Summary
Part of #702. Restores Redshift reserved-node purchases with the library dedupe from LeanerCloud/cloud-commitments-go#515, while Redshift re-drive and retry stay refused. This is option A from the scope question on #702; the retry half stays open there.
08fe7bafchore(deps): bumpsproviders/awstoaeb8a6f7ff51andpkgto541e05e5fd29, which aws requires forPurchaseOptions.RequestedAt. azure and gcp stay at3def3f898617.6db77b04fix(purchase):executeSinglePurchasesetsopts.RequestedAt = time.Now().UTC()right before the singlePurchaseCommitmentcall. Every dispatch path (scheduler, approve, execute-now, scheduled fire, fan-out per account) goes through it.RequestedAt, and the platform always sends a token. The two commits must ship together.cba71250docs(known-issues):known_issues/39_redshift_dedupe_window.mdrecords the unbounded match window. A same account/region/offering/node-count purchase within about 5 minutes of a completed one adopts the earlier node without buying. An unknown outcome followed by a new same-tuple purchase outside the window can double-buy.Why the go caller contract holds
go requires that no second same-tuple Redshift purchase is dispatched while an earlier lineage can still be re-driven. Redshift re-drive and retry remain refused on every path, and this PR does not touch them:
awsPurchaseHasNoDuplicateGuard/recRedriveRefusalReason(RecoverStrandedApprovals);armedRedriveRefusal(pre-existing armed successors);Behaviour changes that ride along with the library bump
Redshift: pre-buy dedupe uses
DescribeReservedNodes(already granted) instead ofDescribeTags(never granted), and node tagging is dropped. Today every Redshift buy is refused before purchase; after this PR, first-dispatch buys go through again. Two concurrent same-tuple purchases are guarded only by go's check-then-act matcher, the per-row execution claim and suppressions.RDS: the offering lookup now refuses at the pagination cap even when a match was found (go#303), so an RDS buy can newly fail with "cannot be proven unique".
RDS:
isLicensedEnginenow also matches the Cost Explorer spelling "sql server" (go#302), so those recommendations are refused like other licensed engines.Savings Plans: the plan type, term and payment are validated before a Cost Explorer
OfferingIDis trusted. This fails loud on a mismatch.Recommendations: Cost Explorer parsing now fails loud.
EstimatedBreakEvenInMonthsdrops that recommendation detail instead of defaulting, and a parsed value is stored inBreakEvenMonths.Rate limiter:
RateLimiter.Waitreturns at once on an already-cancelled context.Adopted nodes look like purchases: when the library adopts an existing node (a guard match, or recovery after an unknown outcome), it sets
PurchaseResult.ExistingCommitment. The platform does not read that field yet, so an adopted node is recorded as an ordinary successful purchase.known_issues/39records this, together with the concurrent same-tuple case.No behaviour change: ElastiCache moves its guard into
internal/purchaseguardwith the same logic. EC2, MemoryDB and OpenSearch have no service code changes between the two versions. Thepkgbreak-even and scorer changes have no consumer in this repo.Verification
Results are posted as PR comments.
🤖 Generated with Claude Code