เรามี http_clients สองตัวในไฟล์บริการที่กำหนดเองของเรา __สร้างหนึ่งค่าดีฟอลต์จาก Drupal's http_client บริการไคลเอ็นต์ใหม่แบบกำหนดเองอื่นที่สร้างขึ้นโดยการใช้ http_client_factory และ http_handler_stack บริการดังต่อไปนี้ ฟังก์ชัน formOptions.
ไคลเอนต์แบบกำหนดเองถูกใช้เพื่อใช้กลไกการลองใหม่ของ guzzle โดยการกด มิดเดิลแวร์::ลองใหม่ ลงใน handler_stack ปัจจุบันในบริการที่กำหนดเองของเรา แต่มิดเดิลแวร์นี้ดูเหมือนจะสอดคล้องกันในค่าเริ่มต้น httpไคลเอนต์ เช่นกันทำให้การโทรของลูกค้าทั้งหมดต้องผ่าน ลองอีกครั้ง Decider().
ส่วนสำคัญของการอ้างอิง
ฉันต้องการแยก Middleware effect ของทั้งสองไคลเอ็นต์ ฉันควรทำอย่างไร
ขอขอบคุณสำหรับการแบ่งปันความรู้ของคุณ!
  /**
   * สร้างวัตถุบริการใหม่
   */
  ฟังก์ชันสาธารณะ __construct (EntityTypeManagerInterface $entity_type_manager, ClientInterface $http_client, ClientFactory $http_client_factory, HandlerStack $stack, TimeInterface $datetime_time, ConfigFactoryInterface $config_factory) {
    $this->entityTypeManager = $entity_type_manager;
    $this->datetimeTime = $datetime_time;
    $this->configFactory = $config_factory;
    $this->httpClient = $http_client;
    // ใช้มิดเดิลแวร์การลองใหม่เพื่อลองใหม่ 2 ครั้ง โดยยึดตามการหมดเวลา 20 วินาที
    $stack->push(Middleware::retry($this->retryDecider(), $this->retryDelay()));
    $this->customClient = $http_client_factory->fromOptions([
      'ตัวจัดการ' => $stack,
      'หมดเวลา' => 20,
    ]);
  }
  /**
   * {@inheritdoc}
   */
  ฟังก์ชันสาธารณะ apiRequest ($type, $method, array $data = [], $retry = FALSE) {
    $client = $ลองใหม่ ? $this->customClient : $this->httpClient;
    สวิตช์ ($ วิธีการ) {
      กรณี "โพสต์":
        $result = $client->request('POST', $this->requestUrl . '/' . $type, [
          'form_params' => $data,
          'ส่วนหัว' => [
            'ยอมรับ' => 'ใบสมัคร/x-www-form-urlencoded',
          ]
        ]
        );
        หยุดพัก;
      กรณี "รับ":
        $result = $client->request('GET', $this->requestUrl . '/' . $type, [
          'query' => $ข้อมูล,
          'ส่วนหัว' => [
            'ยอมรับ' => 'แอปพลิเคชัน/json',
          ]
        ]
        );
        หยุดพัก;
      กรณี "PATCH":
        $result = $client->request('PATCH', $this->requestUrl . '/' . $type, [
          'form_params' => $data,
          'ส่วนหัว' => [
            'ยอมรับ' => 'ใบสมัคร/x-www-form-urlencoded',
          ]
        ]);
    }
    $apiRequest = $result->getBody()->getContents();
    ส่งคืน json_decode($apiRequest);
  }
  /**
   * ตัวตัดสินบูลีนของความพยายามลองใหม่สำหรับ Guzzle
   */
  ฟังก์ชันที่ได้รับการป้องกัน retryDecider () {
    ฟังก์ชันส่งคืน (
      $ลองใหม่
      ขอ $request,
      การตอบสนอง $response = NULL,
      RequestException $exception = โมฆะ
   ) {
      ถ้า ((0 < $ ลองใหม่) && ($ ลองใหม่ <= 2)) {
        $this->getLogger('API')->info('%uniqid SystemAction retryDecider msg="ลองใหม่ %การลองใหม่"', [
          '%uniqid' => $this->uniqid,
          '%ลองใหม่' => $ลองใหม่
        ]);
      }
      // จำกัดจำนวนครั้งในการลองใหม่เป็น 3 ครั้ง
      ถ้า ($ ลองใหม่ >= 2) {
        $this->getLogger('API')->info('%uniqid SystemAction retryDecider msg="Attempt on Retry for Guzzle Client"', [
          '%uniqid' => $this->uniqid,
        ]);
        กลับ FALSE;
      }
      // ลองข้อยกเว้นการเชื่อมต่ออีกครั้ง
      ถ้า (อินสแตนซ์ข้อยกเว้น $ ของ ConnectException) {
        กลับ TRUE;
      }
      ถ้า (การตอบสนอง $) {
        // ลองอีกครั้งในข้อผิดพลาดของเซิร์ฟเวอร์
        ถ้า ($response->getStatusCode() >= 500) {
          กลับ TRUE;
        }
      }
      กลับ FALSE;
    };
  }
  /**
   * ความล่าช้าของการลองใหม่แต่ละครั้งระหว่างการพยายามร้องขอ
   */
  ฟังก์ชันที่ได้รับการป้องกัน retryDelay() {
    ฟังก์ชันส่งคืน ($ numberOfRetries) {
      ส่งคืน 1,000 * $numberOfRetries;
    };
  }