mirror of https://github.com/grpc/grpc-node.git
grpc-js: Add pick tracing and one error handler
This commit is contained in:
parent
b46d0f1db5
commit
bc3e6a1adc
|
@ -37,7 +37,7 @@ import { CompressionFilterFactory } from './compression-filter';
|
||||||
import { getDefaultAuthority } from './resolver';
|
import { getDefaultAuthority } from './resolver';
|
||||||
import { LoadBalancingConfig } from './load-balancing-config';
|
import { LoadBalancingConfig } from './load-balancing-config';
|
||||||
import { ServiceConfig, validateServiceConfig } from './service-config';
|
import { ServiceConfig, validateServiceConfig } from './service-config';
|
||||||
import { trace } from './logging';
|
import { trace, log } from './logging';
|
||||||
import { SubchannelAddress } from './subchannel';
|
import { SubchannelAddress } from './subchannel';
|
||||||
|
|
||||||
export enum ConnectivityState {
|
export enum ConnectivityState {
|
||||||
|
@ -212,6 +212,18 @@ export class ChannelImplementation implements Channel {
|
||||||
*/
|
*/
|
||||||
private tryPick(callStream: Http2CallStream, callMetadata: Metadata) {
|
private tryPick(callStream: Http2CallStream, callMetadata: Metadata) {
|
||||||
const pickResult = this.currentPicker.pick({ metadata: callMetadata });
|
const pickResult = this.currentPicker.pick({ metadata: callMetadata });
|
||||||
|
trace(
|
||||||
|
LogVerbosity.DEBUG,
|
||||||
|
'channel',
|
||||||
|
'Pick result: ' +
|
||||||
|
PickResultType[pickResult.pickResultType] +
|
||||||
|
' subchannel: ' +
|
||||||
|
pickResult.subchannel?.getAddress() +
|
||||||
|
' status: ' +
|
||||||
|
pickResult.status?.code +
|
||||||
|
' ' +
|
||||||
|
pickResult.status?.details
|
||||||
|
);
|
||||||
switch (pickResult.pickResultType) {
|
switch (pickResult.pickResultType) {
|
||||||
case PickResultType.COMPLETE:
|
case PickResultType.COMPLETE:
|
||||||
if (pickResult.subchannel === null) {
|
if (pickResult.subchannel === null) {
|
||||||
|
@ -221,16 +233,29 @@ export class ChannelImplementation implements Channel {
|
||||||
);
|
);
|
||||||
// End the call with an error
|
// End the call with an error
|
||||||
} else {
|
} else {
|
||||||
/* If the subchannel disconnects between calling pick and getting
|
/* If the subchannel is not in the READY state, that indicates a bug
|
||||||
* the filter stack metadata, the call will end with an error. */
|
* somewhere in the load balancer or picker. So, we log an error and
|
||||||
|
* queue the pick to be tried again later. */
|
||||||
|
if (
|
||||||
|
pickResult.subchannel!.getConnectivityState() !==
|
||||||
|
ConnectivityState.READY
|
||||||
|
) {
|
||||||
|
log(
|
||||||
|
LogVerbosity.ERROR,
|
||||||
|
'Error: COMPLETE pick result subchannel ' +
|
||||||
|
pickResult.subchannel!.getAddress() +
|
||||||
|
' has state ' +
|
||||||
|
ConnectivityState[pickResult.subchannel!.getConnectivityState()]
|
||||||
|
);
|
||||||
|
this.pickQueue.push({ callStream, callMetadata });
|
||||||
|
break;
|
||||||
|
}
|
||||||
callStream.filterStack
|
callStream.filterStack
|
||||||
.sendMetadata(Promise.resolve(callMetadata))
|
.sendMetadata(Promise.resolve(callMetadata))
|
||||||
.then(
|
.then(
|
||||||
finalMetadata => {
|
finalMetadata => {
|
||||||
if (
|
const subchannelState: ConnectivityState = pickResult.subchannel!.getConnectivityState();
|
||||||
pickResult.subchannel!.getConnectivityState() ===
|
if (subchannelState === ConnectivityState.READY) {
|
||||||
ConnectivityState.READY
|
|
||||||
) {
|
|
||||||
try {
|
try {
|
||||||
pickResult.subchannel!.startCallStream(
|
pickResult.subchannel!.startCallStream(
|
||||||
finalMetadata,
|
finalMetadata,
|
||||||
|
@ -250,11 +275,27 @@ export class ChannelImplementation implements Channel {
|
||||||
* the stream because the correct behavior may be
|
* the stream because the correct behavior may be
|
||||||
* re-queueing instead, based on the logic in the rest of
|
* re-queueing instead, based on the logic in the rest of
|
||||||
* tryPick */
|
* tryPick */
|
||||||
|
trace(
|
||||||
|
LogVerbosity.INFO,
|
||||||
|
'channel',
|
||||||
|
'Failed to start call on picked subchannel ' +
|
||||||
|
pickResult.subchannel!.getAddress() +
|
||||||
|
'. Retrying pick'
|
||||||
|
);
|
||||||
this.tryPick(callStream, callMetadata);
|
this.tryPick(callStream, callMetadata);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* The logic for doing this here is the same as in the catch
|
/* The logic for doing this here is the same as in the catch
|
||||||
* block above */
|
* block above */
|
||||||
|
trace(
|
||||||
|
LogVerbosity.INFO,
|
||||||
|
'channel',
|
||||||
|
'Picked subchannel ' +
|
||||||
|
pickResult.subchannel!.getAddress() +
|
||||||
|
' has state ' +
|
||||||
|
ConnectivityState[subchannelState] +
|
||||||
|
' after metadata filters. Retrying pick'
|
||||||
|
);
|
||||||
this.tryPick(callStream, callMetadata);
|
this.tryPick(callStream, callMetadata);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue