diff --git a/src/authorizer/index.ts b/src/authorizer/index.ts index f5ab282..76fb54a 100644 --- a/src/authorizer/index.ts +++ b/src/authorizer/index.ts @@ -30,7 +30,10 @@ import { createClient, Interceptor, } from "@connectrpc/connect"; -import { createGrpcTransport } from "@connectrpc/connect-node"; +import { + createGrpcTransport, + Http2SessionOptions, +} from "@connectrpc/connect-node"; import { handleError, setHeader, traceMessage } from "../util/connect"; import { TopazRegistry } from "../util/serializer"; @@ -65,6 +68,7 @@ type AuthorizerConfig = { caFile?: string; insecure?: boolean; customHeaders?: { [key: string]: unknown }; + http2SessionOptions?: Http2SessionOptions; }; type Path = { @@ -104,6 +108,7 @@ export class Authorizer { baseUrl: serviceUrl, interceptors: interceptors, nodeOptions: baseNodeOptions, + ...config?.http2SessionOptions, }); this.AuthClient = createClient(AuthorizerClient, baseGrpcTransport); diff --git a/src/directory/index.ts b/src/directory/index.ts index 4a8f92c..cf6aa6e 100644 --- a/src/directory/index.ts +++ b/src/directory/index.ts @@ -206,12 +206,15 @@ export class Directory { const nodeOptions = createNodeOptions(config); let customHeaders = Object.assign({}, fallback?.customHeaders || {}); customHeaders = Object.assign(customHeaders, config?.customHeaders || {}); + const http2SessionOptions = + config?.http2SessionOptions || fallback?.http2SessionOptions; if ( serviceUrl !== baseServiceUrl || apiKey !== baseApiKey || tenantId !== baseTenantId || - nodeOptions !== baseNodeOptions + nodeOptions !== baseNodeOptions || + http2SessionOptions !== baseHttp2SessionOptions ) { const interceptors = [createHeadersInterceptor(apiKey, tenantId)]; if (process.env.NODE_TRACE_MESSAGE) { @@ -222,6 +225,7 @@ export class Directory { baseUrl: serviceUrl || "https://localhost:9292", interceptors: interceptors, nodeOptions: nodeOptions, + ...http2SessionOptions, }); } return baseGrpcTransport; @@ -241,9 +245,9 @@ export class Directory { } const baseServiceUrl = config.url; - const baseApiKey = config.apiKey; const baseTenantId = config.tenantId; + const baseHttp2SessionOptions = config.http2SessionOptions; const baseCaFile = !!config.caFile ? readFileSync(config.caFile) : undefined; @@ -263,6 +267,7 @@ export class Directory { baseUrl: baseServiceUrl || "https://localhost:9292", interceptors: interceptors, nodeOptions: baseNodeOptions, + ...baseHttp2SessionOptions, }) : undefined; diff --git a/src/directory/types.ts b/src/directory/types.ts index 103f52c..06124c3 100644 --- a/src/directory/types.ts +++ b/src/directory/types.ts @@ -56,6 +56,7 @@ import { Registry, } from "@bufbuild/protobuf"; import { Timestamp } from "@bufbuild/protobuf/wkt"; +import { Http2SessionOptions } from "@connectrpc/connect-node"; import { NestedOmit, NestedOptional, Optional } from "../util/types"; @@ -276,6 +277,7 @@ export type ServiceConfig = { caFile?: string; insecure?: boolean; customHeaders?: CustomHeaders; + http2SessionOptions?: Http2SessionOptions; }; export type SetManifestResponse = Omit< SetManifestResponse$, diff --git a/tests/directory/v3/index.test.ts b/tests/directory/v3/index.test.ts index 3481f9e..95fdb84 100644 --- a/tests/directory/v3/index.test.ts +++ b/tests/directory/v3/index.test.ts @@ -14,6 +14,7 @@ import { DeleteObjectResponseSchema, DeleteRelationResponseSchema, Directory, + DirectoryConfig, EtagMismatchError, ExportResponseSchema, GetGraphResponseSchema, @@ -48,6 +49,7 @@ describe("Directory", () => { customHeaders: { foo: "bar", }, + idleConnectionTimeoutMs: 60000, }; const directory = new Directory(config); @@ -67,7 +69,7 @@ describe("Directory", () => { return path as string; }); - const config = { + const config: DirectoryConfig = { url: "https://localhost:9292", tenantId: "tenantId", apiKey: "apiKey", @@ -75,6 +77,9 @@ describe("Directory", () => { customHeaders: { base: "bar", }, + http2SessionOptions: { + idleConnectionTimeoutMs: 60000, + }, reader: { url: "https://readerUrl", apiKey: "readerApiKey", @@ -83,6 +88,9 @@ describe("Directory", () => { customHeaders: { reader: "bar", }, + http2SessionOptions: { + idleConnectionTimeoutMs: 60000, + }, }, writer: { url: "https://writerUrl", @@ -91,21 +99,33 @@ describe("Directory", () => { customHeaders: { writer: "bar", }, + http2SessionOptions: { + idleConnectionTimeoutMs: 60000, + }, }, importer: { url: "https://importerUrl", apiKey: "importerApiKey", tenantId: "importerTenantId", + http2SessionOptions: { + idleConnectionTimeoutMs: 60000, + }, }, exporter: { caFile: "exporterCaFile", customHeaders: {}, + http2SessionOptions: { + idleConnectionTimeoutMs: 60000, + }, }, model: { apiKey: "modelApiKey", tenantId: "modelTenantId", + http2SessionOptions: { + idleConnectionTimeoutMs: 60000, + }, }, - rejectUnauthorized: true, + insecure: false, }; const directory = new Directory(config); @@ -119,6 +139,7 @@ describe("Directory", () => { ca: "caFile", rejectUnauthorized: true, }, + idleConnectionTimeoutMs: 60000, }), ], [ @@ -129,6 +150,7 @@ describe("Directory", () => { ca: "readerCaFile", rejectUnauthorized: true, }, + idleConnectionTimeoutMs: 60000, }), ], [ @@ -139,6 +161,7 @@ describe("Directory", () => { ca: "caFile", rejectUnauthorized: true, }, + idleConnectionTimeoutMs: 60000, }), ], [ @@ -149,6 +172,7 @@ describe("Directory", () => { ca: "caFile", rejectUnauthorized: true, }, + idleConnectionTimeoutMs: 60000, }), ], [ @@ -159,6 +183,7 @@ describe("Directory", () => { ca: "exporterCaFile", rejectUnauthorized: true, }, + idleConnectionTimeoutMs: 60000, }), ], [ @@ -169,6 +194,7 @@ describe("Directory", () => { ca: "caFile", rejectUnauthorized: true, }, + idleConnectionTimeoutMs: 60000, }), ], ]); @@ -189,6 +215,7 @@ describe("Directory", () => { url: "localhost:9292", tenantId: "tenantId", apiKey: "apiKey", + idleConnectionTimeoutMs: 60000, reader: { url: "readerUrl", apiKey: "readerApiKey",