Що SDK надсилає ще раз і скільки чекає

PHP

Які запити SDK повторює сам і після якої паузи, які відповіді він не повторює ніколи, що обмежує кожен тайм-аут SDK і який ідентифікатор виклик може дати своєму запиту.

5 хв читання

Запит SDK може лишитися без відповіді або тимчасово отримати відмову: минув час, обірвалося з’єднання, ключ уперся в ліміт запитів, Slen зайнятий. SDK сам надсилає такий запит ще раз, під тим самим ключем ідемпотентності, тому робота робиться один раз. Ця сторінка каже, які запити повторюються, після якої паузи, які відповіді не повторюються ніколи і що обмежує кожен тайм-аут.

Що SDK надсилає ще раз

Що повернулосяНадсилається ще раз?Пауза перед повтором
Немає відповіді — TimeoutException або ConnectionException у PHP, TimeoutError або ConnectionError у Node.jsТак200 мілісекунд, удвічі довше перед кожним наступним повтором, не більше п’яти секунд
429 — ліміт запитів ключаТакСкільки просить заголовок Retry-After відповіді, до 30 секунд; без заголовка — як тоді, коли відповіді не було
503 — service_unavailable, ledger_unavailable, pool_exhaustedТакТак само, як після 429
  • Запит надсилається ще раз стільки разів, скільки каже опція retries: двічі, якщо ви не задали інше число, для SDK чи для одного виклику — нижче. 0 вимикає повтори.

  • Кожна пауза зсувається до чверті в будь-який бік, щоб клієнти, які впали разом, не повернулися разом.

  • На відповідь, яка просить зачекати довше за 30 секунд, не чекають: виклик одразу кидає свою помилку, а retryAfterSeconds помилки каже, скільки API просив зачекати.

  • Коли повтори вичерпано, виклик кидає помилку останньої спроби.

Будь-який виклик SDK можна надіслати ще раз. Читання й зміна клієнта лишають той самий стан, скільки б разів їх не надіслали. Запуск і рух кредитів несуть ключ ідемпотентності, і Slen відповідає на повтор під ним, а не робить роботу знову, — Ключі ідемпотентності. Видалення клієнта, на яке відповіли 404 із кодом customer_not_found після спроби без відповіді, вважається зробленим: клієнта видалила перша спроба.

Що SDK не надсилає ще раз ніколи

  • 500, 502 і 504. Провайдера могли викликати й оплатити, перш ніж відповідь загубилася. Чи надсилати запуск ще раз — вирішувати вам; що кожна помилка означає для грошей, каже стаття Обробка помилок.

  • Будь-яка інша відповідь API — відмова, перевірка запиту, конфлікт. Вона кидається одразу.

Очікування — виняток з обох списків: executions.wait() надсилає кожне читання статусу один раз і читає його наново після своєї паузи, як описує стаття Асинхронні запуски й очікування.

Тайм-аути

Тайм-аут обмежує одну спробу запиту, а не запит із його повторами.

  • timeout — скільки може тривати одна спроба, від відкриття з’єднання до кінця відповіді. 65 секунд, якщо ви не задали інше.

  • connectTimeout — скільки може відкриватися з’єднання. П’ять секунд, якщо ви не задали інше.

Обидва — у секундах, і дріб допустимий: 0.5 — пів секунди. SDK віддає їх HTTP-клієнтові, якого збирає сам, — Guzzle або Symfony HttpClient. Клієнт, якого ви передали як httpClient, або інший клієнт, знайдений у вашому застосунку, зберігає свої тайм-аути — Конфігурація.

Значення за замовчуванням трохи більше за хвилину вибрано не випадково. Slen дає одній спробі провайдера 60 секунд, якщо сервіс не налаштовано інакше. Клієнт, який кладе слухавку раніше, може втратити відповідь, яку провайдер ще пише, — а за цей виклик, можливо, уже заплатили. Коли виклик іде через пул провайдерів, який може пробувати кілька підключень одне за одним, збільште тайм-аут.

Запит із повторами може тривати його тайм-аут, помножений на кількість спроб, плюс паузи між ними. Очікування має власний тайм-аут — Асинхронні запуски й очікування.

Тайм-аут і повтори одного виклику

Виклик може задати власний тайм-аут і власну кількість повторів. Вони замінюють значення SDK лише для цього виклику, а retries, що дорівнює 0, надсилає його один раз.

  • timeout і retries — іменовані аргументи опцій виклику: RequestOptions або опцій цього виклику, наприклад ExecuteOptions запуску. timeout — у секундах.

  • Тайм-аут виклику доходить до Guzzle і Symfony HttpClient — і коли SDK зібрав його сам, і коли ви передали його як httpClient. Будь-який інший HTTP-клієнт зберігає свої тайм-аути, і SDK пише у свій журнал slen.config.timeout_not_applied, коли виклик просить тайм-аут, — Журнал.

  • Тайм-аут, який не є числом більше за нуль, і від’ємна кількість повторів відхиляються до надсилання запиту, з кодом invalid_request.

executions.wait() не приймає ні того, ні іншого: його обмежує власний тайм-аут, і кожне читання він надсилає один раз — Асинхронні запуски й очікування.

Запуск усередині вашого власного запиту не має тривати довше за цей запит. Зі значеннями за замовчуванням виклик може зайняти понад три хвилини: по 65 секунд на кожну з трьох спроб і паузи між ними. Тайм-аут 20 секунд і retries, що дорівнює 0, дають виклику одну спробу не довше за 20 секунд. Виконання не губиться, коли виклик здається: повтор під тим самим ключем відповідає ним таким, яким воно є, — Надіслати запит.

Власний ідентифікатор запиту

Виклик може сам назвати свій запит — requestId своїх опцій. SDK надсилає його заголовком X-Request-Id, тим самим на кожній спробі виклику, і API відповідає під ним: результат, помилка, журнал SDK і логи Slen несуть ваш ідентифікатор — і помилка виклику, який узагалі не отримав відповіді, теж, — тож ваше трасування й трасування Slen сходяться, — Об’єкти відповіді.

requestId — іменований аргумент опцій виклику: RequestOptions, ExecuteOptions, MovementOptions та інших опцій виклику, який надсилає запит. WaitOptions його не має.

  • Ідентифікатор — від 8 до 128 символів: латинські літери, цифри, ., _, : і -, наприклад order-42:charge. Будь-яке інше значення відхиляється до надсилання запиту, з кодом invalid_request: API замінив би його власним ідентифікатором.

  • customers.listAll() і customers.entriesAll() відхиляють його так само: кожна сторінка — запит, а один ідентифікатор називає один запит. Передайте його в customers.list() або customers.entries().

  • executions.wait() читає статус багато разів і його не приймає.

Що читати далі