feat(Storage): implement GCS idempotency tokens for all API operations- #10 - #9490
Open
salilg-eng wants to merge 4 commits into
Open
feat(Storage): implement GCS idempotency tokens for all API operations- #10#9490salilg-eng wants to merge 4 commits into
salilg-eng wants to merge 4 commits into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
kalragauri
approved these changes
Aug 13, 2026
| <?php | ||
|
|
||
| /** | ||
| * Copyright 2024 Google Inc. All Rights Reserved. |
| /** | ||
| * Test idempotency token and custom headers are preserved across retries. | ||
| */ | ||
| public function testIdempotencyTokenResusedOnRetry() |
| private function addToken(RequestInterface $request, array $options) | ||
| { | ||
| $method = strtoupper($request->getMethod()); | ||
| if ($method === 'GET' || $method === 'HEAD' || $method === 'OPTIONS') { |
There was a problem hiding this comment.
nit: consider using in_array here to make this more readable.
| 'name' => $name | ||
| ]); | ||
|
|
||
| $uuid = \Ramsey\Uuid\Uuid::uuid4()->toString(); |
There was a problem hiding this comment.
nit: consider adding use Ramsey\Uuid\Uuid; (here and below) for consistency with other test methods.
salilg-eng
force-pushed
the
feat/idempotency-token
branch
from
August 13, 2026 07:38
66b4ed7 to
02d4e0f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds support for GCS Idempotency Tokens to the Storage client (Fixes #280811217).
The goal here is to send a unique x-goog-gcs-idempotency-token header (UUID) on all JSON API requests. This allows the backend to safely retry operations without the risk of duplicating them.
To get this working correctly across the board—especially for resumable upload chunks which bypass Rest.php—I subclassed RequestWrapper into a new StorageRequestWrapper. This lets us hook into the very bottom of the request flow just for Storage, without polluting the shared google/cloud-core package.
A few technical notes on how it behaves:
Standard Retries: Because we inject the token right before the ExponentialBackoff loop runs, normal retries (like 5xx or 429) will correctly reuse the exact same token.
Mid-stream Downloads: If a download drops mid-stream and we have to fire off a new byte-range request to resume, the retry listener in Rest.php explicitly generates a brand new token for it, as required by the spec.
Header Alignment: To keep things clean, it extracts and reuses the UUID from the gccl-invocation-id metric header when available, rather than generating a second redundant UUID.
Idempotency Config: I moved objects.delete, insert, patch, and update from being conditionally idempotent to fully idempotent in RetryTrait. Since we're sending tokens now, the backend safely handles idempotency for these operations natively.
I've also updated the unit tests in RestTest.php to validate the new wrapper and ensure the token is being preserved or regenerated in the right scenarios. All tests are passing locally!