Skip to content

Commit

Permalink
Expose used Agent instance in RestResponse; improve keep-alive timeou…
Browse files Browse the repository at this point in the history
…ts logic (#1)

Pull Request: #1 (main)
  • Loading branch information
dimikot authored Jan 12, 2024
1 parent 559d6e9 commit 56bffdd
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 68 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# RestClient: a syntax sugar tool around Node fetch() API, tailored to work with typescript-is or superstruct validators
# rest-client: a syntax sugar tool around Node fetch() API, tailored to work with typescript-is or superstruct validators

See also [Full API documentation](https://github.com/clickup/rest-client/blob/master/docs/modules.md).

Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@clickup/rest-client / [Exports](modules.md)

# RestClient: a syntax sugar tool around Node fetch() API, tailored to work with typescript-is or superstruct validators
# rest-client: a syntax sugar tool around Node fetch() API, tailored to work with typescript-is or superstruct validators

See also [Full API documentation](https://github.com/clickup/rest-client/blob/master/docs/modules.md).

Expand Down
27 changes: 19 additions & 8 deletions docs/classes/RestResponse.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,22 @@ body and make it a part of RestResponse abstraction.

### constructor

**new RestResponse**(`req`, `status`, `headers`, `text`, `textIsPartial`)
**new RestResponse**(`req`, `agent`, `status`, `headers`, `text`, `textIsPartial`)

#### Parameters

| Name | Type |
| :------ | :------ |
| `req` | [`RestRequest`](RestRequest.md)<`any`\> |
| `agent` | ``null`` \| `Agent` |
| `status` | `number` |
| `headers` | `Headers` |
| `text` | `string` |
| `textIsPartial` | `boolean` |

#### Defined in

[src/RestResponse.ts:17](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L17)
[src/RestResponse.ts:18](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L18)

## Properties

Expand All @@ -40,7 +41,17 @@ body and make it a part of RestResponse abstraction.

#### Defined in

[src/RestResponse.ts:18](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L18)
[src/RestResponse.ts:19](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L19)

___

### agent

`Readonly` **agent**: ``null`` \| `Agent`

#### Defined in

[src/RestResponse.ts:20](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L20)

___

Expand All @@ -50,7 +61,7 @@ ___

#### Defined in

[src/RestResponse.ts:19](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L19)
[src/RestResponse.ts:21](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L21)

___

Expand All @@ -60,7 +71,7 @@ ___

#### Defined in

[src/RestResponse.ts:20](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L20)
[src/RestResponse.ts:22](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L22)

___

Expand All @@ -70,7 +81,7 @@ ___

#### Defined in

[src/RestResponse.ts:21](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L21)
[src/RestResponse.ts:23](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L23)

___

Expand All @@ -80,7 +91,7 @@ ___

#### Defined in

[src/RestResponse.ts:22](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L22)
[src/RestResponse.ts:24](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L24)

## Accessors

Expand All @@ -107,4 +118,4 @@ RestRequest.json() instead.

#### Defined in

[src/RestResponse.ts:40](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L40)
[src/RestResponse.ts:42](https://github.com/clickup/rest-client/blob/master/src/RestResponse.ts#L42)
41 changes: 20 additions & 21 deletions docs/interfaces/RestOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ web app, and we don't want to retry them.

#### Defined in

[src/RestOptions.ts:69](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L69)
[src/RestOptions.ts:70](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L70)

___

Expand All @@ -28,7 +28,7 @@ How much time to wait by default on the 1st retry attempt.

#### Defined in

[src/RestOptions.ts:71](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L71)
[src/RestOptions.ts:72](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L72)

___

Expand All @@ -40,7 +40,7 @@ How much to increase the retry delay on each retry.

#### Defined in

[src/RestOptions.ts:73](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L73)
[src/RestOptions.ts:74](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L74)

___

Expand All @@ -53,7 +53,7 @@ Use this fraction (random) of the current retry delay to jitter both ways

#### Defined in

[src/RestOptions.ts:76](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L76)
[src/RestOptions.ts:77](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L77)

___

Expand All @@ -65,7 +65,7 @@ Maximum delay between each retry.

#### Defined in

[src/RestOptions.ts:78](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L78)
[src/RestOptions.ts:79](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L79)

___

Expand All @@ -84,7 +84,7 @@ A logic which runs on different IO stages (delay and heartbeats).

#### Defined in

[src/RestOptions.ts:80](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L80)
[src/RestOptions.ts:81](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L81)

___

Expand All @@ -96,7 +96,7 @@ Allows to limit huge requests and throw instead.

#### Defined in

[src/RestOptions.ts:91](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L91)
[src/RestOptions.ts:92](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L92)

___

Expand All @@ -109,7 +109,7 @@ response or not.

#### Defined in

[src/RestOptions.ts:94](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L94)
[src/RestOptions.ts:95](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L95)

___

Expand All @@ -122,7 +122,7 @@ addresses are allowed.

#### Defined in

[src/RestOptions.ts:97](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L97)
[src/RestOptions.ts:98](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L98)

___

Expand All @@ -134,7 +134,7 @@ If true, logs request-response pairs to console.

#### Defined in

[src/RestOptions.ts:99](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L99)
[src/RestOptions.ts:100](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L100)

___

Expand All @@ -148,13 +148,12 @@ Sets Keep-Alive parameters (persistent connections).

| Name | Type | Description |
| :------ | :------ | :------ |
| `timeout` | `number` | A hint to the server, how much time to keep the connection alive. Not all the servers respect it though (e.g. nginx and express do not). |
| `max` | `number` | How many requests are allowed to be processed in one connection. |
| `timeoutMs` | `number` | How much time to keep an idle connection alive in the pool. If 0, closes the connection immediately after the response. |
| `maxSockets?` | `number` | How many sockets at maximum will be kept open. |

#### Defined in

[src/RestOptions.ts:103](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L103)
[src/RestOptions.ts:104](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L104)

___

Expand All @@ -166,7 +165,7 @@ When resolving DNS, use IPv4, IPv6 or both (see dns.lookup() docs).

#### Defined in

[src/RestOptions.ts:113](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L113)
[src/RestOptions.ts:112](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L112)

___

Expand All @@ -178,7 +177,7 @@ Max timeout to wait for a response.

#### Defined in

[src/RestOptions.ts:115](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L115)
[src/RestOptions.ts:114](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L114)

___

Expand All @@ -205,7 +204,7 @@ delay events logging.

#### Defined in

[src/RestOptions.ts:118](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L118)
[src/RestOptions.ts:117](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L117)

___

Expand All @@ -217,7 +216,7 @@ Middlewares to wrap requests. May alter both request and response.

#### Defined in

[src/RestOptions.ts:120](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L120)
[src/RestOptions.ts:119](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L119)

___

Expand Down Expand Up @@ -254,7 +253,7 @@ remote API is that weird. Return values:

#### Defined in

[src/RestOptions.ts:134](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L134)
[src/RestOptions.ts:132](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L132)

___

Expand Down Expand Up @@ -288,7 +287,7 @@ contradictory information; then isRateLimitError wins.

#### Defined in

[src/RestOptions.ts:144](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L144)
[src/RestOptions.ts:142](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L142)

___

Expand All @@ -315,7 +314,7 @@ not, the response ought to be either success or some other error.

#### Defined in

[src/RestOptions.ts:149](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L149)
[src/RestOptions.ts:147](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L147)

___

Expand Down Expand Up @@ -348,4 +347,4 @@ retry will happen in not less than this number of milliseconds.

#### Defined in

[src/RestOptions.ts:157](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L157)
[src/RestOptions.ts:155](https://github.com/clickup/rest-client/blob/master/src/RestOptions.ts#L155)
2 changes: 1 addition & 1 deletion docs/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ On each call, the inner function needs to return an array with two elements:

| Name | Type |
| :------ | :------ |
| `readFunc` | (`cursor`: `undefined` \| `TCursor`) => `Promise`<[`TItem`[], `undefined` \| ``null`` \| `TCursor`]\> |
| `readFunc` | (`cursor`: `undefined` \| `TCursor`) => `Promise`<readonly [`TItem`[], `undefined` \| ``null`` \| `TCursor`]\> |

#### Returns

Expand Down
14 changes: 6 additions & 8 deletions src/RestOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface Middleware {
*/
interface AgentOptions {
keepAlive: boolean;
timeout?: number;
maxSockets?: number;
rejectUnauthorized?: boolean;
family?: 4 | 6 | 0;
Expand Down Expand Up @@ -101,11 +102,9 @@ export default interface RestOptions {
agents: Agents;
/** Sets Keep-Alive parameters (persistent connections). */
keepAlive: {
/** A hint to the server, how much time to keep the connection alive. Not
* all the servers respect it though (e.g. nginx and express do not). */
timeout: number;
/** How many requests are allowed to be processed in one connection. */
max: number;
/** How much time to keep an idle connection alive in the pool. If 0, closes
* the connection immediately after the response. */
timeoutMs: number;
/** How many sockets at maximum will be kept open. */
maxSockets?: number;
};
Expand All @@ -129,8 +128,7 @@ export default interface RestOptions {
* performed;
* * "THROW" - the request resulted in error. Additional tests will be
* performed to determine is the error is retriable, is OAuth token good,
* and etc.
*/
* and etc. */
isSuccessResponse: (res: RestResponse) => "SUCCESS" | "THROW" | "BEST_EFFORT";
/** Decides whether the response is a rate-limit error or not. Returning
* non-zero value is treated as retry delay (if retries are set up). In case
Expand Down Expand Up @@ -176,7 +174,7 @@ export const DEFAULT_OPTIONS: RestOptions = {
allowInternalIPs: false,
isDebug: false,
agents: new Agents(),
keepAlive: { timeout: 10, max: 100 },
keepAlive: { timeoutMs: 10000 },
family: 4, // we don't want to hit ~5s DNS timeout on a missing IPv6 by default
timeoutMs: 4 * 60 * 1000,
logger: () => {},
Expand Down
37 changes: 15 additions & 22 deletions src/RestRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ export default class RestRequest<TAssertShape = any> {
reader = req._createFetchReader(fetchReq);
await reader.preload(preloadChars);
} finally {
res =
req._createRestResponse(reader) ??
new RestResponse(req, 0, new Headers(), "", false);
res = reader
? req._createRestResponse(reader)
: new RestResponse(req, null, 0, new Headers(), "", false);
}

throwIfErrorResponse(req.options, res);
Expand Down Expand Up @@ -293,16 +293,9 @@ export default class RestRequest<TAssertShape = any> {
redirectMode = "error";
}

const hasKeepAlive = this.options.keepAlive.timeout > 0;
const hasKeepAlive = this.options.keepAlive.timeoutMs > 0;
if (hasKeepAlive) {
headers.append("connection", "Keep-Alive");
headers.append(
"keep-alive",
"timeout=" +
this.options.keepAlive.timeout +
", max=" +
this.options.keepAlive.max
);
}

// Use lazily created/cached per-RestClient Agent instance to utilize HTTP
Expand All @@ -313,7 +306,8 @@ export default class RestRequest<TAssertShape = any> {
: this.options.agents.http.bind(this.options.agents)
)({
keepAlive: hasKeepAlive,
maxSockets: this.options.keepAlive?.maxSockets,
timeout: hasKeepAlive ? this.options.keepAlive.timeoutMs : undefined,
maxSockets: this.options.keepAlive.maxSockets,
rejectUnauthorized: this.options.allowInternalIPs ? false : undefined,
family: this.options.family,
});
Expand Down Expand Up @@ -360,16 +354,15 @@ export default class RestRequest<TAssertShape = any> {
* Creates a RestResponse from a RestFetchReader. Assumes that
* RestFetchReader.preload() has already been called.
*/
private _createRestResponse(reader: RestFetchReader | null) {
return reader
? new RestResponse(
this,
reader.status,
reader.headers,
reader.textFetched,
reader.textIsPartial
)
: null;
private _createRestResponse(reader: RestFetchReader) {
return new RestResponse(
this,
reader.agent,
reader.status,
reader.headers,
reader.textFetched,
reader.textIsPartial
);
}

/**
Expand Down
Loading

0 comments on commit 56bffdd

Please sign in to comment.