Что 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()читает статус много раз и его не принимает.
Что читать дальше
Конфигурация — как задаются опции SDK.
Обработка ошибок — ошибки, которые выбрасывает вызов, и стоил ли запуск денег.
Ключи идемпотентности — ключ, по которому узнают повтор.
Запросы — лимит запросов ключа.