diff --git a/packages/grpc-js/src/channel-options.ts b/packages/grpc-js/src/channel-options.ts index cf310319..1120ab84 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -90,7 +90,7 @@ export const recognizedOptions = { 'grpc.max_connection_age_grace_ms': true, 'grpc-node.max_session_memory': true, 'grpc.service_config_disable_resolution': true, - 'grpc.client_idle_timeout_ms': true + 'grpc.client_idle_timeout_ms': true, }; export function channelOptionsEqual( diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index 6a11028e..1eff3cf2 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -20,7 +20,12 @@ import { ChannelOptions } from './channel-options'; import { ResolvingLoadBalancer } from './resolving-load-balancer'; import { SubchannelPool, getSubchannelPool } from './subchannel-pool'; import { ChannelControlHelper } from './load-balancer'; -import { UnavailablePicker, Picker, PickResultType, QueuePicker } from './picker'; +import { + UnavailablePicker, + Picker, + PickResultType, + QueuePicker, +} from './picker'; import { Metadata } from './metadata'; import { Status, LogVerbosity, Propagate } from './constants'; import { FilterStackFactory } from './filter-stack'; @@ -191,9 +196,10 @@ export class InternalChannel { private currentResolutionError: StatusObject | null = null; private readonly retryBufferTracker: MessageBufferTracker; private keepaliveTime: number; - private readonly wrappedSubchannels: Set = new Set(); + private readonly wrappedSubchannels: Set = + new Set(); - private callCount: number = 0; + private callCount = 0; private idleTimer: NodeJS.Timer | null = null; private readonly idleTimeoutMs: number; @@ -274,7 +280,10 @@ export class InternalChannel { DEFAULT_PER_RPC_RETRY_BUFFER_SIZE_BYTES ); this.keepaliveTime = options['grpc.keepalive_time_ms'] ?? -1; - this.idleTimeoutMs = Math.max(options['grpc.client_idle_timeout_ms'] ?? DEFAULT_IDLE_TIMEOUT_MS, MIN_IDLE_TIMEOUT_MS); + this.idleTimeoutMs = Math.max( + options['grpc.client_idle_timeout_ms'] ?? DEFAULT_IDLE_TIMEOUT_MS, + MIN_IDLE_TIMEOUT_MS + ); const channelControlHelper: ChannelControlHelper = { createSubchannel: ( subchannelAddress: SubchannelAddress, @@ -567,7 +576,11 @@ export class InternalChannel { private maybeStartIdleTimer() { if (this.callCount === 0) { this.idleTimer = setTimeout(() => { - this.trace('Idle timer triggered after ' + this.idleTimeoutMs + 'ms of inactivity'); + this.trace( + 'Idle timer triggered after ' + + this.idleTimeoutMs + + 'ms of inactivity' + ); this.enterIdle(); }, this.idleTimeoutMs); this.idleTimer.unref?.(); diff --git a/packages/grpc-js/test/common.ts b/packages/grpc-js/test/common.ts index 14fec91f..26192d3e 100644 --- a/packages/grpc-js/test/common.ts +++ b/packages/grpc-js/test/common.ts @@ -20,7 +20,12 @@ import * as assert2 from './assert2'; import * as path from 'path'; import * as grpc from '../src'; -import { GrpcObject, ServiceClientConstructor, ServiceClient, loadPackageDefinition } from '../src/make-client'; +import { + GrpcObject, + ServiceClientConstructor, + ServiceClient, + loadPackageDefinition, +} from '../src/make-client'; import { readFileSync } from 'fs'; const protoLoaderOptions = { @@ -67,7 +72,9 @@ export class TestServer { start(): Promise { let credentials: grpc.ServerCredentials; if (this.useTls) { - credentials = grpc.ServerCredentials.createSsl(null, [{private_key: key, cert_chain: cert}]); + credentials = grpc.ServerCredentials.createSsl(null, [ + { private_key: key, cert_chain: cert }, + ]); } else { credentials = grpc.ServerCredentials.createInsecure(); } diff --git a/packages/grpc-js/test/test-idle-timer.ts b/packages/grpc-js/test/test-idle-timer.ts index 646d0e07..3fdeb1f6 100644 --- a/packages/grpc-js/test/test-idle-timer.ts +++ b/packages/grpc-js/test/test-idle-timer.ts @@ -17,7 +17,7 @@ import * as assert from 'assert'; import * as grpc from '../src'; -import { TestClient, TestServer } from "./common"; +import { TestClient, TestServer } from './common'; describe('Channel idle timer', () => { let server: TestServer; @@ -31,30 +31,46 @@ describe('Channel idle timer', () => { client.close(); client = null; } - }) + }); after(() => { server.shutdown(); }); - it('Should go idle after the specified time after a request ends', function(done) { + it('Should go idle after the specified time after a request ends', function (done) { this.timeout(5000); - client = TestClient.createFromServer(server, {'grpc.client_idle_timeout_ms': 1000}); + client = TestClient.createFromServer(server, { + 'grpc.client_idle_timeout_ms': 1000, + }); client.sendRequest(error => { assert.ifError(error); - assert.strictEqual(client!.getChannelState(), grpc.connectivityState.READY); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.READY + ); setTimeout(() => { - assert.strictEqual(client!.getChannelState(), grpc.connectivityState.IDLE); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.IDLE + ); done(); }, 1100); }); }); - it('Should be able to make a request after going idle', function(done) { + it('Should be able to make a request after going idle', function (done) { this.timeout(5000); - client = TestClient.createFromServer(server, {'grpc.client_idle_timeout_ms': 1000}); + client = TestClient.createFromServer(server, { + 'grpc.client_idle_timeout_ms': 1000, + }); client.sendRequest(error => { assert.ifError(error); - assert.strictEqual(client!.getChannelState(), grpc.connectivityState.READY); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.READY + ); setTimeout(() => { - assert.strictEqual(client!.getChannelState(), grpc.connectivityState.IDLE); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.IDLE + ); client!.sendRequest(error => { assert.ifError(error); done(); @@ -62,34 +78,53 @@ describe('Channel idle timer', () => { }, 1100); }); }); - it('Should go idle after the specified time after waitForReady ends', function(done) { + it('Should go idle after the specified time after waitForReady ends', function (done) { this.timeout(5000); - client = TestClient.createFromServer(server, {'grpc.client_idle_timeout_ms': 1000}); + client = TestClient.createFromServer(server, { + 'grpc.client_idle_timeout_ms': 1000, + }); const deadline = new Date(); deadline.setSeconds(deadline.getSeconds() + 3); client.waitForReady(deadline, error => { assert.ifError(error); - assert.strictEqual(client!.getChannelState(), grpc.connectivityState.READY); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.READY + ); setTimeout(() => { - assert.strictEqual(client!.getChannelState(), grpc.connectivityState.IDLE); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.IDLE + ); done(); }, 1100); }); }); - it('Should ensure that the timeout is at least 1 second', function(done) { - client = TestClient.createFromServer(server, {'grpc.client_idle_timeout_ms': 50}); + it('Should ensure that the timeout is at least 1 second', function (done) { + client = TestClient.createFromServer(server, { + 'grpc.client_idle_timeout_ms': 50, + }); client.sendRequest(error => { assert.ifError(error); - assert.strictEqual(client!.getChannelState(), grpc.connectivityState.READY); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.READY + ); setTimeout(() => { // Should still be ready after 100ms - assert.strictEqual(client!.getChannelState(), grpc.connectivityState.READY); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.READY + ); setTimeout(() => { // Should go IDLE after another second - assert.strictEqual(client!.getChannelState(), grpc.connectivityState.IDLE); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.IDLE + ); done(); }, 1000); }, 100); }); - }) -}); \ No newline at end of file + }); +});