Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

grpc-js: Different handling for errors when starting streams #1251

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions packages/grpc-js/src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 that something went 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 is 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 }) => {
Expand Down