What the SDK sends again, and how long it waits
PHPWhich requests the SDK repeats by itself and after which pause, which answers it never repeats, and what each timeout of the SDK bounds.
5 min read
A request of the SDK can be left without an answer, or be turned away for a moment: the time runs out, the connection fails, the rate limit of the key is reached, Slen is busy. The SDK sends such a request again by itself, under the same idempotency key, so the work is done once. This page says which requests are repeated, after which pause, which answers are never repeated, and what each timeout bounds.
What the SDK sends again
| What came back | Sent again? | The pause before the repeat |
|---|---|---|
No answer — TimeoutException or ConnectionException in PHP, TimeoutError or ConnectionError in Node.js | Yes | 200 milliseconds, twice as long before each next repeat, at most five seconds |
429 — the rate limit of the key | Yes | What the Retry-After header of the answer asks for, up to 30 seconds; without the header, as after no answer |
503 — service_unavailable, ledger_unavailable, pool_exhausted | Yes | The same as after a 429 |
A request is sent again as many times as the
retriesoption says: twice unless you set another number, for the SDK or for one call — below.0turns the repeats off.Every pause is shifted by up to a quarter either way, so that clients that failed together do not come back together.
An answer that asks to wait longer than 30 seconds is not waited for: the call raises its error at once, and
retryAfterSecondsof the error says how long the API asked to wait.When the repeats are used up, the call raises the error of the last attempt.
Every call of the SDK may be sent again. A read and a change of a customer leave the same state however many times they are sent. A run and a movement of credits carry an idempotency key, and Slen answers a repeat under it instead of doing the work again — Idempotency keys. A deletion of a customer that is answered 404 with the code customer_not_found after an attempt that got no answer counts as done: the first attempt deleted the customer.
What the SDK never sends again
500,502and504. A provider may have been called and paid for before the answer was lost. Whether to send the run again is your decision — Handling errors says what each error means for the money.Any other answer of the API — a refusal, a check of the request, a conflict. It is raised at once.
A wait is the exception to both lists: executions.wait() sends each read of the status once and reads it anew after its own pause, as Async runs and waiting describes.
The timeouts
A timeout bounds one attempt of a request, not the request with its repeats.
timeout— how long one attempt may take, from opening the connection to the end of the answer. 65 seconds unless you set another.connectTimeout— how long the connection may take to open. Five seconds unless you set another.
Both are seconds, and a fraction is allowed: 0.5 is half a second. The SDK gives them to the HTTP client it builds itself, Guzzle or Symfony HttpClient. A client you pass as httpClient, or another client found in your application, keeps its own timeouts — Configuration.
The default of a little over a minute is not arbitrary. Slen gives one attempt of a provider 60 seconds, unless the service is set up otherwise. A client that hangs up sooner may lose an answer the provider is still writing — and that call may already have been paid for. Behind a provider pool that may try several connections one after another, raise it.
A request with repeats can take as long as its timeout, once for each attempt, plus the pauses between them. A wait has a timeout of its own — Async runs and waiting.
The timeout and the repeats of one call
A call can set a timeout and a number of repeats of its own. They replace those of the SDK for that call alone, and retries set to 0 sends it once.
timeoutandretriesare named arguments of the options of the call:RequestOptions, or the options of that call, such asExecuteOptionsof a run.timeoutis in seconds.The timeout of a call reaches Guzzle and Symfony HttpClient, whether the SDK built the client or you passed it as
httpClient. Any other HTTP client keeps its own timeouts, and the SDK writesslen.config.timeout_not_appliedto its journal when a call asks for one — Logging.A timeout that is not a number above zero and a negative number of repeats are refused before the request is sent, with the code
invalid_request.
executions.wait() takes neither: its own timeout bounds it, and it sends each read once — Async runs and waiting.
A run inside a request of your own should not outlast that request. With the defaults a call can take more than three minutes: 65 seconds for each of three attempts, and the pauses between them. A timeout of 20 seconds and retries set to 0 give the call one attempt of 20 seconds at most. The execution is not lost when the call gives up: a repeat under the same key answers with it as it is — Send a request.
Where to go next
Configuration — how the options of the SDK are set.
Handling errors — the errors a call raises, and whether the run cost money.
Idempotency keys — the key a repeat is known by.
Requests — the rate limit of a key.