diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 4d07dde03..2c8906c4d 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -381,9 +381,9 @@ export class ChannelImplementation implements Channel { const watchersCopy = this.connectivityStateWatchers.slice(); for (const watcherObject of watchersCopy) { if (newState !== watcherObject.currentState) { - watcherObject.callback(); clearTimeout(watcherObject.timer); this.removeConnectivityStateWatcher(watcherObject); + watcherObject.callback(); } } } diff --git a/packages/grpc-js/test/test-client.ts b/packages/grpc-js/test/test-client.ts new file mode 100644 index 000000000..da20c246b --- /dev/null +++ b/packages/grpc-js/test/test-client.ts @@ -0,0 +1,71 @@ +/* + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import * as assert from 'assert'; + +import * as grpc from '../src'; +import { Server, ServerCredentials } from '../src'; +import { Client } from '../src'; +import { ConnectivityState } from '../src/channel'; + +const clientInsecureCreds = grpc.credentials.createInsecure(); +const serverInsecureCreds = ServerCredentials.createInsecure(); + +describe('Client', () => { + let server: Server; + let client: Client; + + before(done => { + server = new Server(); + + server.bindAsync( + 'localhost:0', + serverInsecureCreds, + (err, port) => { + assert.ifError(err); + client = new Client( + `localhost:${port}`, + clientInsecureCreds + ); + server.start(); + done(); + } + ); + }); + + after(done => { + client.close(); + server.tryShutdown(done); + }); + + it('should call the waitForReady callback only once, when channel connectivity state is READY', done => { + const deadline = Date.now() + 100; + let calledTimes = 0; + client.waitForReady(deadline, err => { + assert.ifError(err); + assert.equal( + client.getChannel().getConnectivityState(true), + ConnectivityState.READY + ); + calledTimes += 1; + }); + setTimeout(() => { + assert.equal(calledTimes, 1); + done(); + }, deadline - Date.now()); + }); +});