From f0e19f1d0d5adef73660bfd840509c5c6eaa0d47 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 4 Feb 2020 10:12:33 -0800 Subject: [PATCH] grpc-js: Different handling for errors when starting streams --- packages/grpc-js/src/channel.ts | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 6cf987cb..96c1dda7 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -142,7 +142,9 @@ export class ChannelImplementation implements Channel { ) { /* The global boolean parameter to getSubchannelPool has the inverse meaning to what * the grpc.use_local_subchannel_pool channel option means. */ - this.subchannelPool = getSubchannelPool((options['grpc.use_local_subchannel_pool'] ?? 0) === 0); + this.subchannelPool = getSubchannelPool( + (options['grpc.use_local_subchannel_pool'] ?? 0) === 0 + ); const channelControlHelper: ChannelControlHelper = { createSubchannel: ( subchannelAddress: string, @@ -234,16 +236,25 @@ export class ChannelImplementation implements Channel { callStream ); } catch (error) { - callStream.cancelWithStatus( - Status.UNAVAILABLE, - 'Failed to start call on picked subchannel' - ); + /* An error here indicates thaat something when wrong with + * the picked subchannel's http2 stream right before we + * tried to start the stream. We are handling a promise + * result here, so this asynchronous with respect to the + * original tryPick call, so calling it again is not + * recursive. We call tryPick immediately instead of + * queueing this pick again because handling the queue is + * triggered by state changes, and we want to immediately + * check if the state has already changed since the + * previous tryPick call. We do this instead of cancelling + * the stream because the correct behavior may be + * re-queueing instead, based on the logic in the rest of + * tryPick */ + this.tryPick(callStream, callMetadata); } } else { - callStream.cancelWithStatus( - Status.UNAVAILABLE, - 'Connection dropped while starting call' - ); + /* The logic for doing this here is the same as in the catch + * block above */ + this.tryPick(callStream, callMetadata); } }, (error: Error & { code: number }) => {