From 209f13ead4707dad6e478578a81d6623b0642776 Mon Sep 17 00:00:00 2001 From: tsightler Date: Fri, 22 Nov 2024 19:30:36 -0500 Subject: [PATCH] Tune fetch for improved connection management (#1532) * Custom fetch keepalive Use a custom fetch agent to reduce total TCP connections/DNS lookups and leverage long-lived HTTPS connections * Create changeset --------- Co-authored-by: Tom Sightler Co-authored-by: dgreif --- .changeset/purple-teachers-applaud.md | 6 ++++++ package-lock.json | 28 +++++++++++++++++++------ packages/ring-client-api/package.json | 1 + packages/ring-client-api/rest-client.ts | 11 ++++++++-- 4 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 .changeset/purple-teachers-applaud.md diff --git a/.changeset/purple-teachers-applaud.md b/.changeset/purple-teachers-applaud.md new file mode 100644 index 00000000..8514422f --- /dev/null +++ b/.changeset/purple-teachers-applaud.md @@ -0,0 +1,6 @@ +--- +'ring-client-api': patch +'homebridge-ring': patch +--- + +Increase keepalive and adjust connection pooling, which will hopefully result in more stable fetch requests diff --git a/package-lock.json b/package-lock.json index ae589bed..8b8c754e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1459,9 +1459,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", + "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", "dev": true, "dependencies": { "levn": "^0.4.1" @@ -9878,6 +9878,15 @@ "node": ">=14.17" } }, + "node_modules/undici": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", + "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -10814,6 +10823,7 @@ "rxjs": "^7.8.1", "socket.io-client": "^2.5.0", "systeminformation": "^5.23.5", + "undici": "^6.21.0", "uuid": "^11.0.3", "werift": "0.20.1", "ws": "^8.18.0" @@ -12005,9 +12015,9 @@ "dev": true }, "@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", + "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", "dev": true, "requires": { "levn": "^0.4.1" @@ -17753,6 +17763,7 @@ "ts-jest": "29.2.5", "tsconfig": "*", "typescript": "5.6.3", + "undici": "^6.21.0", "uuid": "^11.0.3", "werift": "0.20.1", "ws": "^8.18.0" @@ -18400,6 +18411,11 @@ "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true }, + "undici": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", + "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==" + }, "undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", diff --git a/packages/ring-client-api/package.json b/packages/ring-client-api/package.json index 1e9abd05..6205a292 100644 --- a/packages/ring-client-api/package.json +++ b/packages/ring-client-api/package.json @@ -26,6 +26,7 @@ "rxjs": "^7.8.1", "socket.io-client": "^2.5.0", "systeminformation": "^5.23.5", + "undici": "^6.21.0", "uuid": "^11.0.3", "werift": "0.20.1", "ws": "^8.18.0" diff --git a/packages/ring-client-api/rest-client.ts b/packages/ring-client-api/rest-client.ts index 2b854305..ba94034c 100644 --- a/packages/ring-client-api/rest-client.ts +++ b/packages/ring-client-api/rest-client.ts @@ -16,14 +16,21 @@ import { import { ReplaySubject } from 'rxjs' import assert from 'assert' import type { Credentials } from '@eneris/push-receiver/dist/types' +import { Agent } from 'undici' interface RequestOptions extends RequestInit { responseType?: 'json' | 'buffer' timeout?: number json?: object + dispatcher?: Agent } -const defaultRequestOptions: RequestOptions = { +const fetchAgent = new Agent({ + connections: 6, + pipelining: 1, + keepAliveTimeout: 115000, + }), + defaultRequestOptions: RequestOptions = { responseType: 'json', method: 'GET', timeout: 20000, @@ -116,6 +123,7 @@ async function requestWithRetry( const options = { ...defaultRequestOptions, ...requestOptions, + dispatcher: fetchAgent, } // If a timeout is provided, create an AbortSignal for it @@ -501,7 +509,6 @@ export class RingRestClient { authorization: `Bearer ${authTokenResponse.access_token}`, hardware_id: hardwareId, 'User-Agent': 'android:com.ringapp', - Connection: 'close', }, }) } catch (e: any) {