ACMPCA
10 months ago
ARCZonalShift
10 months ago
AccessAnalyzer
10 months ago
Account
10 months ago
Acm
10 months ago
AlexaForBusiness
10 months ago
Amplify
10 months ago
AmplifyBackend
10 months ago
AmplifyUIBuilder
10 months ago
Api
10 months ago
ApiGateway
10 months ago
ApiGatewayManagementApi
10 months ago
ApiGatewayV2
10 months ago
AppConfig
10 months ago
AppConfigData
10 months ago
AppFabric
10 months ago
AppIntegrationsService
10 months ago
AppMesh
10 months ago
AppRegistry
10 months ago
AppRunner
10 months ago
AppSync
10 months ago
Appflow
10 months ago
ApplicationAutoScaling
10 months ago
ApplicationCostProfiler
10 months ago
ApplicationDiscoveryService
10 months ago
ApplicationInsights
10 months ago
Appstream
10 months ago
Arn
10 months ago
Athena
10 months ago
AuditManager
10 months ago
AugmentedAIRuntime
10 months ago
AutoScaling
10 months ago
AutoScalingPlans
10 months ago
B2bi
10 months ago
BCMDataExports
10 months ago
Backup
10 months ago
BackupGateway
10 months ago
BackupStorage
10 months ago
Batch
10 months ago
Bedrock
10 months ago
BedrockAgent
10 months ago
BedrockAgentRuntime
10 months ago
BedrockRuntime
10 months ago
BillingConductor
10 months ago
Braket
10 months ago
Budgets
10 months ago
Chime
10 months ago
ChimeSDKIdentity
10 months ago
ChimeSDKMediaPipelines
10 months ago
ChimeSDKMeetings
10 months ago
ChimeSDKMessaging
10 months ago
ChimeSDKVoice
10 months ago
CleanRooms
10 months ago
CleanRoomsML
10 months ago
ClientSideMonitoring
10 months ago
Cloud9
10 months ago
CloudControlApi
10 months ago
CloudDirectory
10 months ago
CloudFormation
10 months ago
CloudFront
10 months ago
CloudFrontKeyValueStore
10 months ago
CloudHSMV2
10 months ago
CloudHsm
10 months ago
CloudSearch
10 months ago
CloudSearchDomain
10 months ago
CloudTrail
10 months ago
CloudTrailData
10 months ago
CloudWatch
10 months ago
CloudWatchEvents
10 months ago
CloudWatchEvidently
10 months ago
CloudWatchLogs
10 months ago
CloudWatchRUM
10 months ago
CodeArtifact
10 months ago
CodeBuild
10 months ago
CodeCatalyst
10 months ago
CodeCommit
10 months ago
CodeDeploy
10 months ago
CodeGuruProfiler
10 months ago
CodeGuruReviewer
10 months ago
CodeGuruSecurity
10 months ago
CodePipeline
10 months ago
CodeStar
10 months ago
CodeStarNotifications
10 months ago
CodeStarconnections
10 months ago
CognitoIdentity
10 months ago
CognitoIdentityProvider
10 months ago
CognitoSync
10 months ago
Comprehend
10 months ago
ComprehendMedical
10 months ago
ComputeOptimizer
10 months ago
ConfigService
10 months ago
Configuration
10 months ago
Connect
10 months ago
ConnectCampaignService
10 months ago
ConnectCases
10 months ago
ConnectContactLens
10 months ago
ConnectParticipant
10 months ago
ConnectWisdomService
10 months ago
ControlTower
10 months ago
CostExplorer
10 months ago
CostOptimizationHub
10 months ago
CostandUsageReportService
10 months ago
Credentials
10 months ago
Crypto
10 months ago
CustomerProfiles
10 months ago
DAX
10 months ago
DLM
10 months ago
DataExchange
10 months ago
DataPipeline
10 months ago
DataSync
10 months ago
DataZone
10 months ago
DatabaseMigrationService
10 months ago
DefaultsMode
10 months ago
Detective
10 months ago
DevOpsGuru
10 months ago
DeviceFarm
10 months ago
DirectConnect
10 months ago
DirectoryService
10 months ago
DocDB
10 months ago
DocDBElastic
10 months ago
DynamoDb
10 months ago
DynamoDbStreams
10 months ago
EBS
10 months ago
EC2InstanceConnect
10 months ago
ECRPublic
10 months ago
EKS
10 months ago
EKSAuth
10 months ago
EMRContainers
10 months ago
EMRServerless
10 months ago
Ec2
10 months ago
Ecr
10 months ago
Ecs
10 months ago
Efs
10 months ago
ElastiCache
10 months ago
ElasticBeanstalk
10 months ago
ElasticInference
10 months ago
ElasticLoadBalancing
10 months ago
ElasticLoadBalancingV2
10 months ago
ElasticTranscoder
10 months ago
ElasticsearchService
10 months ago
Emr
10 months ago
Endpoint
10 months ago
EndpointDiscovery
10 months ago
EndpointV2
10 months ago
EntityResolution
10 months ago
EventBridge
10 months ago
Exception
10 months ago
FIS
10 months ago
FMS
10 months ago
FSx
10 months ago
FinSpaceData
10 months ago
Firehose
10 months ago
ForecastQueryService
10 months ago
ForecastService
10 months ago
FraudDetector
10 months ago
FreeTier
10 months ago
GameLift
10 months ago
Glacier
10 months ago
GlobalAccelerator
10 months ago
Glue
10 months ago
GlueDataBrew
10 months ago
Greengrass
10 months ago
GreengrassV2
10 months ago
GroundStation
10 months ago
GuardDuty
10 months ago
Handler
10 months ago
Health
10 months ago
HealthLake
10 months ago
Honeycode
10 months ago
IVS
10 months ago
IVSRealTime
10 months ago
Iam
10 months ago
Identity
10 months ago
IdentityStore
10 months ago
ImportExport
10 months ago
Inspector
10 months ago
Inspector2
10 months ago
InspectorScan
10 months ago
InternetMonitor
10 months ago
IoT1ClickDevicesService
10 months ago
IoT1ClickProjects
10 months ago
IoTAnalytics
10 months ago
IoTDeviceAdvisor
10 months ago
IoTEvents
10 months ago
IoTEventsData
10 months ago
IoTFleetHub
10 months ago
IoTFleetWise
10 months ago
IoTJobsDataPlane
10 months ago
IoTRoboRunner
10 months ago
IoTSecureTunneling
10 months ago
IoTSiteWise
10 months ago
IoTThingsGraph
10 months ago
IoTTwinMaker
10 months ago
IoTWireless
10 months ago
Iot
10 months ago
IotDataPlane
10 months ago
Kafka
10 months ago
KafkaConnect
10 months ago
KendraRanking
10 months ago
Keyspaces
10 months ago
Kinesis
10 months ago
KinesisAnalytics
10 months ago
KinesisAnalyticsV2
10 months ago
KinesisVideo
10 months ago
KinesisVideoArchivedMedia
10 months ago
KinesisVideoMedia
10 months ago
KinesisVideoSignalingChannels
10 months ago
KinesisVideoWebRTCStorage
10 months ago
Kms
10 months ago
LakeFormation
10 months ago
Lambda
10 months ago
LaunchWizard
10 months ago
LexModelBuildingService
10 months ago
LexModelsV2
10 months ago
LexRuntimeService
10 months ago
LexRuntimeV2
10 months ago
LicenseManager
10 months ago
LicenseManagerLinuxSubscriptions
10 months ago
LicenseManagerUserSubscriptions
10 months ago
Lightsail
10 months ago
LocationService
10 months ago
LookoutEquipment
10 months ago
LookoutMetrics
10 months ago
LookoutforVision
10 months ago
MQ
10 months ago
MTurk
10 months ago
MWAA
10 months ago
MachineLearning
10 months ago
Macie2
10 months ago
MainframeModernization
10 months ago
ManagedBlockchain
10 months ago
ManagedBlockchainQuery
10 months ago
ManagedGrafana
10 months ago
MarketplaceAgreement
10 months ago
MarketplaceCatalog
10 months ago
MarketplaceCommerceAnalytics
10 months ago
MarketplaceDeployment
10 months ago
MarketplaceEntitlementService
10 months ago
MarketplaceMetering
10 months ago
MediaConnect
10 months ago
MediaConvert
10 months ago
MediaLive
10 months ago
MediaPackage
10 months ago
MediaPackageV2
10 months ago
MediaPackageVod
10 months ago
MediaStore
10 months ago
MediaStoreData
10 months ago
MediaTailor
10 months ago
MedicalImaging
10 months ago
MemoryDB
10 months ago
MigrationHub
10 months ago
MigrationHubConfig
10 months ago
MigrationHubOrchestrator
10 months ago
MigrationHubRefactorSpaces
10 months ago
MigrationHubStrategyRecommendations
10 months ago
Mobile
10 months ago
Multipart
10 months ago
Neptune
10 months ago
Neptunedata
10 months ago
NetworkFirewall
10 months ago
NetworkManager
10 months ago
NimbleStudio
10 months ago
OAM
10 months ago
OSIS
10 months ago
Omics
10 months ago
OpenSearchServerless
10 months ago
OpenSearchService
10 months ago
OpsWorks
10 months ago
OpsWorksCM
10 months ago
Organizations
10 months ago
Outposts
10 months ago
PI
10 months ago
Panorama
10 months ago
PaymentCryptography
10 months ago
PaymentCryptographyData
10 months ago
PcaConnectorAd
10 months ago
Personalize
10 months ago
PersonalizeEvents
10 months ago
PersonalizeRuntime
10 months ago
Pinpoint
10 months ago
PinpointEmail
10 months ago
PinpointSMSVoice
10 months ago
PinpointSMSVoiceV2
10 months ago
Pipes
10 months ago
Polly
10 months ago
Pricing
10 months ago
PrivateNetworks
10 months ago
PrometheusService
10 months ago
Proton
10 months ago
QBusiness
10 months ago
QConnect
10 months ago
QLDB
10 months ago
QLDBSession
10 months ago
QuickSight
10 months ago
RAM
10 months ago
RDSDataService
10 months ago
Rds
10 months ago
RecycleBin
10 months ago
Redshift
10 months ago
RedshiftDataAPIService
10 months ago
RedshiftServerless
10 months ago
Rekognition
10 months ago
Repostspace
10 months ago
ResilienceHub
10 months ago
ResourceExplorer2
10 months ago
ResourceGroups
10 months ago
ResourceGroupsTaggingAPI
10 months ago
Retry
10 months ago
RoboMaker
10 months ago
RolesAnywhere
10 months ago
Route53
10 months ago
Route53Domains
10 months ago
Route53RecoveryCluster
10 months ago
Route53RecoveryControlConfig
10 months ago
Route53RecoveryReadiness
10 months ago
Route53Resolver
10 months ago
S3
10 months ago
S3Control
10 months ago
S3Outposts
10 months ago
SSMContacts
10 months ago
SSMIncidents
10 months ago
SSO
10 months ago
SSOAdmin
10 months ago
SSOOIDC
10 months ago
SageMaker
10 months ago
SageMakerFeatureStoreRuntime
10 months ago
SageMakerGeospatial
10 months ago
SageMakerMetrics
10 months ago
SageMakerRuntime
10 months ago
SagemakerEdgeManager
10 months ago
SavingsPlans
10 months ago
Scheduler
10 months ago
Schemas
10 months ago
Script
10 months ago
SecretsManager
10 months ago
SecurityHub
10 months ago
SecurityLake
10 months ago
ServerlessApplicationRepository
10 months ago
ServiceCatalog
10 months ago
ServiceDiscovery
10 months ago
ServiceQuotas
10 months ago
Ses
10 months ago
SesV2
10 months ago
Sfn
10 months ago
Shield
10 months ago
Signature
10 months ago
SimSpaceWeaver
10 months ago
Sms
10 months ago
SnowBall
10 months ago
SnowDeviceManagement
10 months ago
Sns
10 months ago
Sqs
10 months ago
Ssm
10 months ago
SsmSap
10 months ago
StorageGateway
10 months ago
Sts
10 months ago
Support
10 months ago
SupportApp
10 months ago
Swf
10 months ago
Synthetics
10 months ago
Textract
10 months ago
TimestreamQuery
10 months ago
TimestreamWrite
10 months ago
Tnb
10 months ago
Token
10 months ago
TranscribeService
10 months ago
Transfer
10 months ago
Translate
10 months ago
TrustedAdvisor
10 months ago
VPCLattice
10 months ago
VerifiedPermissions
10 months ago
VoiceID
10 months ago
WAFV2
10 months ago
Waf
10 months ago
WafRegional
10 months ago
WellArchitected
10 months ago
WorkDocs
10 months ago
WorkLink
10 months ago
WorkMail
10 months ago
WorkMailMessageFlow
10 months ago
WorkSpaces
10 months ago
WorkSpacesThinClient
10 months ago
WorkSpacesWeb
10 months ago
XRay
10 months ago
data
10 months ago
drs
10 months ago
finspace
10 months ago
imagebuilder
10 months ago
ivschat
10 months ago
kendra
10 months ago
mgn
10 months ago
signer
10 months ago
AbstractConfigurationProvider.php
10 months ago
AwsClient.php
10 months ago
AwsClientInterface.php
10 months ago
AwsClientTrait.php
10 months ago
CacheInterface.php
10 months ago
ClientResolver.php
10 months ago
Command.php
10 months ago
CommandInterface.php
10 months ago
CommandPool.php
10 months ago
ConfigurationProviderInterface.php
10 months ago
DoctrineCacheAdapter.php
10 months ago
EndpointParameterMiddleware.php
10 months ago
HandlerList.php
10 months ago
HasDataTrait.php
10 months ago
HasMonitoringEventsTrait.php
10 months ago
HashInterface.php
10 months ago
HashingStream.php
10 months ago
History.php
10 months ago
IdempotencyTokenMiddleware.php
10 months ago
InputValidationMiddleware.php
10 months ago
JsonCompiler.php
10 months ago
LruArrayCache.php
10 months ago
Middleware.php
10 months ago
MockHandler.php
10 months ago
MonitoringEventsInterface.php
10 months ago
MultiRegionClient.php
10 months ago
PhpHash.php
10 months ago
PresignUrlMiddleware.php
10 months ago
Psr16CacheAdapter.php
10 months ago
PsrCacheAdapter.php
10 months ago
QueryCompatibleInputMiddleware.php
10 months ago
RequestCompressionMiddleware.php
10 months ago
ResponseContainerInterface.php
10 months ago
Result.php
10 months ago
ResultInterface.php
10 months ago
ResultPaginator.php
10 months ago
RetryMiddleware.php
10 months ago
RetryMiddlewareV2.php
10 months ago
Sdk.php
10 months ago
StreamRequestPayloadMiddleware.php
10 months ago
TraceMiddleware.php
10 months ago
Waiter.php
10 months ago
WrappedHttpHandler.php
10 months ago
functions.php
10 months ago
RetryMiddleware.php
278 lines
| 1 | <?php |
| 2 | namespace Aws; |
| 3 | |
| 4 | use Aws\Exception\AwsException; |
| 5 | use Aws\Retry\RetryHelperTrait; |
| 6 | use GuzzleHttp\Exception\RequestException; |
| 7 | use Psr\Http\Message\RequestInterface; |
| 8 | use GuzzleHttp\Promise\PromiseInterface; |
| 9 | use GuzzleHttp\Promise; |
| 10 | |
| 11 | /** |
| 12 | * Middleware that retries failures. V1 implemention that supports 'legacy' mode. |
| 13 | * |
| 14 | * @internal |
| 15 | */ |
| 16 | class RetryMiddleware |
| 17 | { |
| 18 | use RetryHelperTrait; |
| 19 | |
| 20 | private static $retryStatusCodes = [ |
| 21 | 500 => true, |
| 22 | 502 => true, |
| 23 | 503 => true, |
| 24 | 504 => true |
| 25 | ]; |
| 26 | |
| 27 | private static $retryCodes = [ |
| 28 | // Throttling error |
| 29 | 'RequestLimitExceeded' => true, |
| 30 | 'Throttling' => true, |
| 31 | 'ThrottlingException' => true, |
| 32 | 'ThrottledException' => true, |
| 33 | 'ProvisionedThroughputExceededException' => true, |
| 34 | 'RequestThrottled' => true, |
| 35 | 'BandwidthLimitExceeded' => true, |
| 36 | 'RequestThrottledException' => true, |
| 37 | 'TooManyRequestsException' => true, |
| 38 | 'IDPCommunicationError' => true, |
| 39 | 'EC2ThrottledException' => true, |
| 40 | ]; |
| 41 | |
| 42 | private $decider; |
| 43 | private $delay; |
| 44 | private $nextHandler; |
| 45 | private $collectStats; |
| 46 | |
| 47 | public function __construct( |
| 48 | callable $decider, |
| 49 | callable $delay, |
| 50 | callable $nextHandler, |
| 51 | $collectStats = false |
| 52 | ) { |
| 53 | $this->decider = $decider; |
| 54 | $this->delay = $delay; |
| 55 | $this->nextHandler = $nextHandler; |
| 56 | $this->collectStats = (bool) $collectStats; |
| 57 | } |
| 58 | |
| 59 | /** |
| 60 | * Creates a default AWS retry decider function. |
| 61 | * |
| 62 | * The optional $extraConfig parameter is an associative array |
| 63 | * that specifies additional retry conditions on top of the ones specified |
| 64 | * by default by the Aws\RetryMiddleware class, with the following keys: |
| 65 | * |
| 66 | * - errorCodes: (string[]) An indexed array of AWS exception codes to retry. |
| 67 | * Optional. |
| 68 | * - statusCodes: (int[]) An indexed array of HTTP status codes to retry. |
| 69 | * Optional. |
| 70 | * - curlErrors: (int[]) An indexed array of Curl error codes to retry. Note |
| 71 | * these should be valid Curl constants. Optional. |
| 72 | * |
| 73 | * @param int $maxRetries |
| 74 | * @param array $extraConfig |
| 75 | * @return callable |
| 76 | */ |
| 77 | public static function createDefaultDecider( |
| 78 | $maxRetries = 3, |
| 79 | $extraConfig = [] |
| 80 | ) { |
| 81 | $retryCurlErrors = []; |
| 82 | if (extension_loaded('curl')) { |
| 83 | $retryCurlErrors[CURLE_RECV_ERROR] = true; |
| 84 | } |
| 85 | |
| 86 | return function ( |
| 87 | $retries, |
| 88 | CommandInterface $command, |
| 89 | RequestInterface $request, |
| 90 | ResultInterface $result = null, |
| 91 | $error = null |
| 92 | ) use ($maxRetries, $retryCurlErrors, $extraConfig) { |
| 93 | // Allow command-level options to override this value |
| 94 | $maxRetries = null !== $command['@retries'] ? |
| 95 | $command['@retries'] |
| 96 | : $maxRetries; |
| 97 | |
| 98 | $isRetryable = self::isRetryable( |
| 99 | $result, |
| 100 | $error, |
| 101 | $retryCurlErrors, |
| 102 | $extraConfig |
| 103 | ); |
| 104 | |
| 105 | if ($retries >= $maxRetries) { |
| 106 | if (!empty($error) |
| 107 | && $error instanceof AwsException |
| 108 | && $isRetryable |
| 109 | ) { |
| 110 | $error->setMaxRetriesExceeded(); |
| 111 | } |
| 112 | return false; |
| 113 | } |
| 114 | |
| 115 | return $isRetryable; |
| 116 | }; |
| 117 | } |
| 118 | |
| 119 | private static function isRetryable( |
| 120 | $result, |
| 121 | $error, |
| 122 | $retryCurlErrors, |
| 123 | $extraConfig = [] |
| 124 | ) { |
| 125 | $errorCodes = self::$retryCodes; |
| 126 | if (!empty($extraConfig['error_codes']) |
| 127 | && is_array($extraConfig['error_codes']) |
| 128 | ) { |
| 129 | foreach($extraConfig['error_codes'] as $code) { |
| 130 | $errorCodes[$code] = true; |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | $statusCodes = self::$retryStatusCodes; |
| 135 | if (!empty($extraConfig['status_codes']) |
| 136 | && is_array($extraConfig['status_codes']) |
| 137 | ) { |
| 138 | foreach($extraConfig['status_codes'] as $code) { |
| 139 | $statusCodes[$code] = true; |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | if (!empty($extraConfig['curl_errors']) |
| 144 | && is_array($extraConfig['curl_errors']) |
| 145 | ) { |
| 146 | foreach($extraConfig['curl_errors'] as $code) { |
| 147 | $retryCurlErrors[$code] = true; |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | if (!$error) { |
| 152 | if (!isset($result['@metadata']['statusCode'])) { |
| 153 | return false; |
| 154 | } |
| 155 | return isset($statusCodes[$result['@metadata']['statusCode']]); |
| 156 | } |
| 157 | |
| 158 | if (!($error instanceof AwsException)) { |
| 159 | return false; |
| 160 | } |
| 161 | |
| 162 | if ($error->isConnectionError()) { |
| 163 | return true; |
| 164 | } |
| 165 | |
| 166 | if (isset($errorCodes[$error->getAwsErrorCode()])) { |
| 167 | return true; |
| 168 | } |
| 169 | |
| 170 | if (isset($statusCodes[$error->getStatusCode()])) { |
| 171 | return true; |
| 172 | } |
| 173 | |
| 174 | if (count($retryCurlErrors) |
| 175 | && ($previous = $error->getPrevious()) |
| 176 | && $previous instanceof RequestException |
| 177 | ) { |
| 178 | if (method_exists($previous, 'getHandlerContext')) { |
| 179 | $context = $previous->getHandlerContext(); |
| 180 | return !empty($context['errno']) |
| 181 | && isset($retryCurlErrors[$context['errno']]); |
| 182 | } |
| 183 | |
| 184 | $message = $previous->getMessage(); |
| 185 | foreach (array_keys($retryCurlErrors) as $curlError) { |
| 186 | if (strpos($message, 'cURL error ' . $curlError . ':') === 0) { |
| 187 | return true; |
| 188 | } |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | return false; |
| 193 | } |
| 194 | |
| 195 | /** |
| 196 | * Delay function that calculates an exponential delay. |
| 197 | * |
| 198 | * Exponential backoff with jitter, 100ms base, 20 sec ceiling |
| 199 | * |
| 200 | * @param $retries - The number of retries that have already been attempted |
| 201 | * |
| 202 | * @return int |
| 203 | * |
| 204 | * @link https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ |
| 205 | */ |
| 206 | public static function exponentialDelay($retries) |
| 207 | { |
| 208 | return mt_rand(0, (int) min(20000, (int) pow(2, $retries) * 100)); |
| 209 | } |
| 210 | |
| 211 | /** |
| 212 | * @param CommandInterface $command |
| 213 | * @param RequestInterface $request |
| 214 | * |
| 215 | * @return PromiseInterface |
| 216 | */ |
| 217 | public function __invoke( |
| 218 | CommandInterface $command, |
| 219 | RequestInterface $request = null |
| 220 | ) { |
| 221 | $retries = 0; |
| 222 | $requestStats = []; |
| 223 | $monitoringEvents = []; |
| 224 | $handler = $this->nextHandler; |
| 225 | $decider = $this->decider; |
| 226 | $delay = $this->delay; |
| 227 | |
| 228 | $request = $this->addRetryHeader($request, 0, 0); |
| 229 | |
| 230 | $g = function ($value) use ( |
| 231 | $handler, |
| 232 | $decider, |
| 233 | $delay, |
| 234 | $command, |
| 235 | $request, |
| 236 | &$retries, |
| 237 | &$requestStats, |
| 238 | &$monitoringEvents, |
| 239 | &$g |
| 240 | ) { |
| 241 | $this->updateHttpStats($value, $requestStats); |
| 242 | |
| 243 | if ($value instanceof MonitoringEventsInterface) { |
| 244 | $reversedEvents = array_reverse($monitoringEvents); |
| 245 | $monitoringEvents = array_merge($monitoringEvents, $value->getMonitoringEvents()); |
| 246 | foreach ($reversedEvents as $event) { |
| 247 | $value->prependMonitoringEvent($event); |
| 248 | } |
| 249 | } |
| 250 | if ($value instanceof \Exception || $value instanceof \Throwable) { |
| 251 | if (!$decider($retries, $command, $request, null, $value)) { |
| 252 | return Promise\Create::rejectionFor( |
| 253 | $this->bindStatsToReturn($value, $requestStats) |
| 254 | ); |
| 255 | } |
| 256 | } elseif ($value instanceof ResultInterface |
| 257 | && !$decider($retries, $command, $request, $value, null) |
| 258 | ) { |
| 259 | return $this->bindStatsToReturn($value, $requestStats); |
| 260 | } |
| 261 | |
| 262 | // Delay fn is called with 0, 1, ... so increment after the call. |
| 263 | $delayBy = $delay($retries++); |
| 264 | $command['@http']['delay'] = $delayBy; |
| 265 | if ($this->collectStats) { |
| 266 | $this->updateStats($retries, $delayBy, $requestStats); |
| 267 | } |
| 268 | |
| 269 | // Update retry header with retry count and delayBy |
| 270 | $request = $this->addRetryHeader($request, $retries, $delayBy); |
| 271 | |
| 272 | return $handler($command, $request)->then($g, $g); |
| 273 | }; |
| 274 | |
| 275 | return $handler($command, $request)->then($g, $g); |
| 276 | } |
| 277 | } |
| 278 |