RetryDomainsMiddleware.php 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. <?php
  2. namespace Qiniu\Http\Middleware;
  3. use Qiniu\Http\Request;
  4. use Qiniu\Http\Response;
  5. class RetryDomainsMiddleware implements Middleware
  6. {
  7. /**
  8. * @var array<string> backup domains.
  9. */
  10. private $backupDomains;
  11. /**
  12. * @var numeric max retry times for each backup domains.
  13. */
  14. private $maxRetryTimes;
  15. /**
  16. * @var callable args response and request; returns bool; If true will retry with backup domains.
  17. */
  18. private $retryCondition;
  19. /**
  20. * @param array<string> $backupDomains
  21. * @param numeric $maxRetryTimes
  22. */
  23. public function __construct($backupDomains, $maxRetryTimes = 2, $retryCondition = null)
  24. {
  25. $this->backupDomains = $backupDomains;
  26. $this->maxRetryTimes = $maxRetryTimes;
  27. $this->retryCondition = $retryCondition;
  28. }
  29. private function shouldRetry($resp, $req)
  30. {
  31. if (is_callable($this->retryCondition)) {
  32. return call_user_func($this->retryCondition, $resp, $req);
  33. }
  34. return !$resp || $resp->needRetry();
  35. }
  36. /**
  37. * @param Request $request
  38. * @param callable(Request): Response $next
  39. * @return Response
  40. */
  41. public function send($request, $next)
  42. {
  43. $response = null;
  44. $urlComponents = parse_url($request->url);
  45. foreach (array_merge(array($urlComponents["host"]), $this->backupDomains) as $backupDomain) {
  46. $urlComponents["host"] = $backupDomain;
  47. $request->url = \Qiniu\unparse_url($urlComponents);
  48. $retriedTimes = 0;
  49. while ($retriedTimes < $this->maxRetryTimes) {
  50. $response = $next($request);
  51. $retriedTimes += 1;
  52. if (!$this->shouldRetry($response, $request)) {
  53. return $response;
  54. }
  55. }
  56. }
  57. if (!$response) {
  58. $response = $next($request);
  59. }
  60. return $response;
  61. }
  62. }