-
Notifications
You must be signed in to change notification settings - Fork 565
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* feat: initial implementation * feat: handle simple scenario * feat: enhance default retry * feat: enhance err * feat: add support for retry-after header * feat: add support for weak etag check * ts: adjust types * refactor: reduce magic * docs: add RetryAfter documentation * refactor: small adjustments * refactor: apply review suggestions * refactor: apply review * feat: set retry async * refactor: apply reviews
- Loading branch information
1 parent
99932f1
commit f996014
Showing
10 changed files
with
1,168 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# Class: RetryHandler | ||
|
||
Extends: `undici.DispatcherHandlers` | ||
|
||
A handler class that implements the retry logic for a request. | ||
|
||
## `new RetryHandler(dispatchOptions, retryHandlers, [retryOptions])` | ||
|
||
Arguments: | ||
|
||
- **options** `Dispatch.DispatchOptions & RetryOptions` (required) - It is an intersection of `Dispatcher.DispatchOptions` and `RetryOptions`. | ||
- **retryHandlers** `RetryHandlers` (required) - Object containing the `dispatch` to be used on every retry, and `handler` for handling the `dispatch` lifecycle. | ||
|
||
Returns: `retryHandler` | ||
|
||
### Parameter: `Dispatch.DispatchOptions & RetryOptions` | ||
|
||
Extends: [`Dispatch.DispatchOptions`](Dispatcher.md#parameter-dispatchoptions). | ||
|
||
#### `RetryOptions` | ||
|
||
- **retry** `(err: Error, context: RetryContext, callback: (err?: Error | null) => void) => void` (optional) - Function to be called after every retry. It should pass error if no more retries should be performed. | ||
- **maxRetries** `number` (optional) - Maximum number of retries. Default: `5` | ||
- **maxTimeout** `number` (optional) - Maximum number of milliseconds to wait before retrying. Default: `30000` (30 seconds) | ||
- **minTimeout** `number` (optional) - Minimum number of milliseconds to wait before retrying. Default: `500` (half a second) | ||
- **timeoutFactor** `number` (optional) - Factor to multiply the timeout by for each retry attempt. Default: `2` | ||
- **retryAfter** `boolean` (optional) - It enables automatic retry after the `Retry-After` header is received. Default: `true` | ||
- | ||
- **methods** `string[]` (optional) - Array of HTTP methods to retry. Default: `['GET', 'PUT', 'HEAD', 'OPTIONS', 'DELETE']` | ||
- **statusCodes** `number[]` (optional) - Array of HTTP status codes to retry. Default: `[429, 500, 502, 503, 504]` | ||
- **errorCodes** `string[]` (optional) - Array of Error codes to retry. Default: `['ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ENETDOWN','ENETUNREACH', 'EHOSTDOWN', | ||
|
||
**`RetryContext`** | ||
|
||
- `state`: `RetryState` - Current retry state. It can be mutated. | ||
- `opts`: `Dispatch.DispatchOptions & RetryOptions` - Options passed to the retry handler. | ||
|
||
### Parameter `RetryHandlers` | ||
|
||
- **dispatch** `(options: Dispatch.DispatchOptions, handlers: Dispatch.DispatchHandlers) => Promise<Dispatch.DispatchResponse>` (required) - Dispatch function to be called after every retry. | ||
- **handler** Extends [`Dispatch.DispatchHandlers`](Dispatcher.md#dispatcherdispatchoptions-handler) (required) - Handler function to be called after the request is successful or the retries are exhausted. | ||
|
||
Examples: | ||
|
||
```js | ||
const client = new Client(`http://localhost:${server.address().port}`); | ||
const chunks = []; | ||
const handler = new RetryHandler( | ||
{ | ||
...dispatchOptions, | ||
retryOptions: { | ||
// custom retry function | ||
retry: function (err, state, callback) { | ||
counter++; | ||
|
||
if (err.code && err.code === "UND_ERR_DESTROYED") { | ||
callback(err); | ||
return; | ||
} | ||
|
||
if (err.statusCode === 206) { | ||
callback(err); | ||
return; | ||
} | ||
|
||
setTimeout(() => callback(null), 1000); | ||
}, | ||
}, | ||
}, | ||
{ | ||
dispatch: (...args) => { | ||
return client.dispatch(...args); | ||
}, | ||
handler: { | ||
onConnect() {}, | ||
onBodySent() {}, | ||
onHeaders(status, _rawHeaders, resume, _statusMessage) { | ||
// do something with headers | ||
}, | ||
onData(chunk) { | ||
chunks.push(chunk); | ||
return true; | ||
}, | ||
onComplete() {}, | ||
onError() { | ||
// handle error properly | ||
}, | ||
}, | ||
} | ||
); | ||
``` | ||
|
||
#### Example - Basic RetryHandler with defaults | ||
|
||
```js | ||
const client = new Client(`http://localhost:${server.address().port}`); | ||
const handler = new RetryHandler(dispatchOptions, { | ||
dispatch: client.dispatch.bind(client), | ||
handler: { | ||
onConnect() {}, | ||
onBodySent() {}, | ||
onHeaders(status, _rawHeaders, resume, _statusMessage) {}, | ||
onData(chunk) {}, | ||
onComplete() {}, | ||
onError(err) {}, | ||
}, | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.