From 25eb3784c712cfc6c2e679f537a2e921dc3cb1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Grabski-Gradzi=C5=84ski?= Date: Sun, 3 Aug 2025 23:01:47 +0000 Subject: [PATCH 1/6] feat(Storage): adding retry configuration example. --- storage/src/configure_retries.php | 123 ++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 storage/src/configure_retries.php diff --git a/storage/src/configure_retries.php b/storage/src/configure_retries.php new file mode 100644 index 0000000000..bfc2138bd3 --- /dev/null +++ b/storage/src/configure_retries.php @@ -0,0 +1,123 @@ + 10, + + // Exponential backoff settings + // Retry strategy to signify that we never want to retry an operation + // even if the error is retryable. + // Default: StorageClient::RETRY_IDEMPOTENT + 'retryStrategy' => StorageClient::RETRY_ALWAYS, + + // Executes a delay + // Defaults to utilizing `usleep`. + // Function signature should match: `function (int $delay) : void`. + 'restDelayFunction' => function ($delay) { + usleep($delay); + }, + + // Sets the conditions for determining how long to wait between attempts to retry. + // Function signature should match: `function (int $attempt) : int`. + // Allows to change the initial retry delay, retry delay multiplier and maximum retry delay. + 'restCalcDelayFunction' => fn ($attempt) => ($attempt + 1) * 100, + + // Sets the conditions for whether or not a request should attempt to retry. + // Function signature should match: `function (\Exception $ex) : bool`. + 'restRetryFunction' => function (\Exception $e) { + // Custom logic: ex. only retry if the error code is 404. + return $e->getCode() === 404; + }, + + // Runs after the restRetryFunction. This might be used to simply consume the + // exception and $arguments b/w retries. This returns the new $arguments thus allowing + // modification on demand for $arguments. For ex: changing the headers in b/w retries. + 'restRetryListener' => function (\Exception $e, $retryAttempt, &$arguments) { + // logic + }, + ]); + $bucket = $storage->bucket($bucketName); + $operationRetriesOverrides = [ + // The maximum number of automatic retries attempted before returning + // the error. + // Default: 3 + 'retries' => 10, + + // Exponential backoff settings + // Retry strategy to signify that we never want to retry an operation + // even if the error is retryable. + // Default: StorageClient::RETRY_IDEMPOTENT + 'retryStrategy' => StorageClient::RETRY_ALWAYS, + + // Executes a delay + // Defaults to utilizing `usleep`. + // Function signature should match: `function (int $delay) : void`. + 'restDelayFunction' => function ($delay) { + usleep($delay); + }, + + // Sets the conditions for determining how long to wait between attempts to retry. + // Function signature should match: `function (int $attempt) : int`. + // Allows to change the initial retry delay, retry delay multiplier and maximum retry delay. + 'restCalcDelayFunction' => fn ($attempt) => ($attempt + 1) * 100, + + // Sets the conditions for whether or not a request should attempt to retry. + // Function signature should match: `function (\Exception $ex) : bool`. + 'restRetryFunction' => function (\Exception $e) { + // Custom logic: ex. only retry if the error code is 404. + return $e->getCode() === 404; + }, + + // Runs after the restRetryFunction. This might be used to simply consume the + // exception and $arguments b/w retries. This returns the new $arguments thus allowing + // modification on demand for $arguments. For ex: changing the headers in b/w retries. + 'restRetryListener' => function (\Exception $e, $retryAttempt, &$arguments) use (&$listenerInvocations6b) { + // logic + }, + ]; + foreach ($bucket->objects($operationRetriesOverrides) as $object) { + printf('Object: %s' . PHP_EOL, $object->name()); + } +} +# [END configure_retries] + +// The following 2 lines are only needed to run the samples +require_once __DIR__ . '/../../testing/sample_helpers.php'; +\Google\Cloud\Samples\execute_sample(__FILE__, __NAMESPACE__, $argv); From 054e76da60a3e3dd094f9bcf4b29af01ee53c044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Grabski-Gradzi=C5=84ski?= Date: Mon, 4 Aug 2025 17:36:37 +0000 Subject: [PATCH 2/6] fix: resolving review comments. --- storage/src/configure_retries.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/storage/src/configure_retries.php b/storage/src/configure_retries.php index bfc2138bd3..f683f24161 100644 --- a/storage/src/configure_retries.php +++ b/storage/src/configure_retries.php @@ -24,7 +24,7 @@ namespace Google\Cloud\Samples\Storage; -# [START configure_retries] +# [START storage_configure_retries] use Google\Cloud\Storage\StorageClient; /** @@ -50,6 +50,8 @@ function configure_retries(string $bucketName): void // Executes a delay // Defaults to utilizing `usleep`. // Function signature should match: `function (int $delay) : void`. + // This function is mostly used internally, so the tests don't wait + // the time of the delay to run. 'restDelayFunction' => function ($delay) { usleep($delay); }, @@ -89,6 +91,8 @@ function configure_retries(string $bucketName): void // Executes a delay // Defaults to utilizing `usleep`. // Function signature should match: `function (int $delay) : void`. + // This function is mostly used internally, so the tests don't wait + // the time of the delay to run. 'restDelayFunction' => function ($delay) { usleep($delay); }, @@ -116,7 +120,7 @@ function configure_retries(string $bucketName): void printf('Object: %s' . PHP_EOL, $object->name()); } } -# [END configure_retries] +# [END storage_configure_retries] // The following 2 lines are only needed to run the samples require_once __DIR__ . '/../../testing/sample_helpers.php'; From 12ea9ac2eb5ad7f942c8aac9ff25564ab791c845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Grabski-Gradzi=C5=84ski?= Date: Tue, 19 Aug 2025 11:15:00 +0000 Subject: [PATCH 3/6] Bumping storage dependency. --- storage/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/composer.json b/storage/composer.json index 085871e33f..5665d3f330 100644 --- a/storage/composer.json +++ b/storage/composer.json @@ -1,6 +1,6 @@ { "require": { - "google/cloud-storage": "^1.28.0", + "google/cloud-storage": "^1.48.0", "paragonie/random_compat": "^9.0.0" }, "require-dev": { From f11f468e648d4e95326023cea247e3036dc5cb39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Grabski-Gradzi=C5=84ski?= Date: Thu, 21 Aug 2025 20:34:14 +0000 Subject: [PATCH 4/6] Bumping storage dependency to v1.48.3. --- storage/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/composer.json b/storage/composer.json index 5665d3f330..3c26e870f8 100644 --- a/storage/composer.json +++ b/storage/composer.json @@ -1,6 +1,6 @@ { "require": { - "google/cloud-storage": "^1.48.0", + "google/cloud-storage": "^1.48.3", "paragonie/random_compat": "^9.0.0" }, "require-dev": { From aa065b48554f0e91e0e294693b5c7919b3cb5b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Grabski-Gradzi=C5=84ski?= Date: Thu, 21 Aug 2025 21:41:40 +0000 Subject: [PATCH 5/6] Fixing linter. --- storage/src/configure_retries.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/src/configure_retries.php b/storage/src/configure_retries.php index f683f24161..5dd9076079 100644 --- a/storage/src/configure_retries.php +++ b/storage/src/configure_retries.php @@ -112,7 +112,7 @@ function configure_retries(string $bucketName): void // Runs after the restRetryFunction. This might be used to simply consume the // exception and $arguments b/w retries. This returns the new $arguments thus allowing // modification on demand for $arguments. For ex: changing the headers in b/w retries. - 'restRetryListener' => function (\Exception $e, $retryAttempt, &$arguments) use (&$listenerInvocations6b) { + 'restRetryListener' => function (\Exception $e, $retryAttempt, &$arguments) { // logic }, ]; From e90b629a7a1d5ca8ed54cec5deb65665a14d1401 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Tue, 26 Aug 2025 08:53:26 -0700 Subject: [PATCH 6/6] remove trailing whitespace --- storage/src/configure_retries.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/storage/src/configure_retries.php b/storage/src/configure_retries.php index 5dd9076079..87656d8f7e 100644 --- a/storage/src/configure_retries.php +++ b/storage/src/configure_retries.php @@ -50,7 +50,7 @@ function configure_retries(string $bucketName): void // Executes a delay // Defaults to utilizing `usleep`. // Function signature should match: `function (int $delay) : void`. - // This function is mostly used internally, so the tests don't wait + // This function is mostly used internally, so the tests don't wait // the time of the delay to run. 'restDelayFunction' => function ($delay) { usleep($delay); @@ -61,15 +61,15 @@ function configure_retries(string $bucketName): void // Allows to change the initial retry delay, retry delay multiplier and maximum retry delay. 'restCalcDelayFunction' => fn ($attempt) => ($attempt + 1) * 100, - // Sets the conditions for whether or not a request should attempt to retry. + // Sets the conditions for whether or not a request should attempt to retry. // Function signature should match: `function (\Exception $ex) : bool`. 'restRetryFunction' => function (\Exception $e) { // Custom logic: ex. only retry if the error code is 404. return $e->getCode() === 404; }, - // Runs after the restRetryFunction. This might be used to simply consume the - // exception and $arguments b/w retries. This returns the new $arguments thus allowing + // Runs after the restRetryFunction. This might be used to simply consume the + // exception and $arguments b/w retries. This returns the new $arguments thus allowing // modification on demand for $arguments. For ex: changing the headers in b/w retries. 'restRetryListener' => function (\Exception $e, $retryAttempt, &$arguments) { // logic @@ -91,7 +91,7 @@ function configure_retries(string $bucketName): void // Executes a delay // Defaults to utilizing `usleep`. // Function signature should match: `function (int $delay) : void`. - // This function is mostly used internally, so the tests don't wait + // This function is mostly used internally, so the tests don't wait // the time of the delay to run. 'restDelayFunction' => function ($delay) { usleep($delay); @@ -102,15 +102,15 @@ function configure_retries(string $bucketName): void // Allows to change the initial retry delay, retry delay multiplier and maximum retry delay. 'restCalcDelayFunction' => fn ($attempt) => ($attempt + 1) * 100, - // Sets the conditions for whether or not a request should attempt to retry. + // Sets the conditions for whether or not a request should attempt to retry. // Function signature should match: `function (\Exception $ex) : bool`. 'restRetryFunction' => function (\Exception $e) { // Custom logic: ex. only retry if the error code is 404. return $e->getCode() === 404; }, - // Runs after the restRetryFunction. This might be used to simply consume the - // exception and $arguments b/w retries. This returns the new $arguments thus allowing + // Runs after the restRetryFunction. This might be used to simply consume the + // exception and $arguments b/w retries. This returns the new $arguments thus allowing // modification on demand for $arguments. For ex: changing the headers in b/w retries. 'restRetryListener' => function (\Exception $e, $retryAttempt, &$arguments) { // logic