MicrosoftAzureStorageCommonInternalRetryMiddlewareFactory

This class provides static functions that creates retry handlers for Guzzle HTTP clients to handle retry policy.

Defined (1)

The class is defined in the following location(s).

/lib/Azure/MicrosoftAzureStorage/Common/Internal/RetryMiddlewareFactory.php  
  1. class RetryMiddlewareFactory 
  2. const LINEAR_INTERVAL_ACCUMULATION = 'Linear'; 
  3. const EXPONENTIAL_INTERVAL_ACCUMULATION = 'Exponential'; 
  4. const GENERAL_RETRY_TYPE = 'General'; 
  5. const APPEND_BLOB_RETRY_TYPE = 'Append Blob Retry'; 
  6.  
  7. /** 
  8. * Create the retry handler for the Guzzle client, according to the given 
  9. * attributes. 
  10. * @param string $type The type that controls the logic of 
  11. * the decider of the retry handler. 
  12. * @param int $numberOfRetries The maximum number of retries. 
  13. * @param int $interval The minimum interval between each retry 
  14. * @param string $accumulationMethod If the interval increases linearly or 
  15. * exponentially. 
  16. * @return RetryMiddleware A RetryMiddleware object that contains 
  17. * the logic of how the request should be 
  18. * handled after a response. 
  19. */ 
  20. public static function create( 
  21. $type = self::GENERAL_RETRY_TYPE,  
  22. $numberOfRetries = Resources::DEFAULT_NUMBER_OF_RETRIES,  
  23. $interval = Resources::DEAFULT_RETRY_INTERVAL,  
  24. $accumulationMethod = self::LINEAR_INTERVAL_ACCUMULATION 
  25. ) { 
  26. //Validate the input parameters 
  27. //type 
  28. Validate::isTrue( 
  29. $type == self::GENERAL_RETRY_TYPE || 
  30. $type == self::APPEND_BLOB_RETRY_TYPE,  
  31. sprintf( 
  32. Resources::INVALID_PARAM_GENERAL,  
  33. 'type' 
  34. ); 
  35. //numberOfRetries 
  36. Validate::isTrue( 
  37. $numberOfRetries > 0,  
  38. sprintf( 
  39. Resources::INVALID_NEGATIVE_PARAM,  
  40. 'numberOfRetries' 
  41. ); 
  42. //interval 
  43. Validate::isTrue( 
  44. $interval > 0,  
  45. sprintf( 
  46. Resources::INVALID_NEGATIVE_PARAM,  
  47. 'interval' 
  48. ); 
  49. //accumulationMethod 
  50. Validate::isTrue( 
  51. $accumulationMethod == self::LINEAR_INTERVAL_ACCUMULATION || 
  52. $accumulationMethod == self::EXPONENTIAL_INTERVAL_ACCUMULATION,  
  53. sprintf( 
  54. Resources::INVALID_PARAM_GENERAL,  
  55. 'accumulationMethod' 
  56. ); 
  57.  
  58. //Get the interval calculator according to the type of the 
  59. //accumulation method. 
  60. $intervalCalculator = 
  61. $accumulationMethod == self::LINEAR_INTERVAL_ACCUMULATION ? 
  62. self::createLinearDelayCalculator($interval) : 
  63. self::createExponentialDelayCalculator($interval); 
  64.  
  65. //Get the retry decider according to the type of the retry and 
  66. //the number of retries. 
  67. $retryDecider = self::createRetryDecider($type, $numberOfRetries); 
  68.  
  69. //construct the retry middle ware. 
  70. return Middleware::retry($retryDecider, $intervalCalculator); 
  71.  
  72. /** 
  73. * Create the retry decider for the retry handler. It will return a callable 
  74. * that accepts the number of retries, the request, the response and the 
  75. * exception, and return the decision for a retry. 
  76. * @param string $type The type of the retry handler. 
  77. * @return callable The callable that will return if the request should 
  78. * be retried. 
  79. */ 
  80. protected static function createRetryDecider($type, $maxRetries) 
  81. return function ( 
  82. $retries,  
  83. $request,  
  84. $response = null,  
  85. $exception = null 
  86. ) use ( 
  87. $type,  
  88. $maxRetries 
  89. ) { 
  90. //Exceeds the retry limit. No retry. 
  91. if ($retries >= $maxRetries) { 
  92. return false; 
  93.  
  94. //Not retriable error, won't retry. 
  95. if (!$response) { 
  96. return false; 
  97. } else { 
  98. if ($type == self::GENERAL_RETRY_TYPE) { 
  99. return self::generalRetryDecider($response->getStatusCode()); 
  100. } else { 
  101. return self::appendBlobRetryDecider($response->getStatusCode()); 
  102.  
  103. return true; 
  104. }; 
  105.  
  106. /** 
  107. * Decide if the given status code indicate the request should be retried. 
  108. * @param int $statusCode status code of the previous request. 
  109. * @return bool true if the request should be retried. 
  110. */ 
  111. protected static function generalRetryDecider($statusCode) 
  112. $retry = false; 
  113. if ($statusCode == 408) { 
  114. $retry = true; 
  115. } elseif ($statusCode >= 500) { 
  116. if ($statusCode != 501 && $statusCode != 505) { 
  117. $retry = true; 
  118. return $retry; 
  119.  
  120. /** 
  121. * Decide if the given status code indicate the request should be retried. 
  122. * This is for append blob. 
  123. * @param int $statusCode status code of the previous request. 
  124. * @return bool true if the request should be retried. 
  125. */ 
  126. protected static function appendBlobRetryDecider($statusCode) 
  127. //The retry logic is different for append blob. 
  128. //First it will need to record the former status code if it is 
  129. //server error. Then if the following request is 412 then it 
  130. //needs to be retried. Currently this is not implemented so will 
  131. //only adapt to the general retry decider. 
  132. //TODO: add logic for append blob's retry when implemented. 
  133. $retry = self::generalRetryDecider($statusCode); 
  134. return $retry; 
  135.  
  136. /** 
  137. * Create the delay calculator that increases the interval linearly 
  138. * according to the number of retries. 
  139. * @param int $interval the minimum interval of the retry. 
  140. * @return callable a calculator that will return the interval 
  141. * according to the number of retries. 
  142. */ 
  143. protected static function createLinearDelayCalculator($interval) 
  144. return function ($retries) use ($interval) { 
  145. return $retries * $interval; 
  146. }; 
  147.  
  148. /** 
  149. * Create the delay calculator that increases the interval exponentially 
  150. * according to the number of retries. 
  151. * @param int $interval the minimum interval of the retry. 
  152. * @return callable a calculator that will return the interval 
  153. * according to the number of retries. 
  154. */ 
  155. protected static function createExponentialDelayCalculator($interval) 
  156. return function ($retries) use ($interval) { 
  157. return $interval * ((int)\pow(2, $retries)); 
  158. };