mirror of https://github.com/grpc/grpc-node.git
Add more tracers, fix onResourceDoesNotExist handling
This commit is contained in:
parent
2404446234
commit
197cc84e7a
|
|
@ -200,7 +200,9 @@ function main() {
|
||||||
|
|
||||||
const loadBalancerStatsServiceImpl: LoadBalancerStatsServiceHandlers = {
|
const loadBalancerStatsServiceImpl: LoadBalancerStatsServiceHandlers = {
|
||||||
GetClientStats: (call, callback) => {
|
GetClientStats: (call, callback) => {
|
||||||
|
console.log(`Received stats request with num_rpcs=${call.request.num_rpcs} and timeout_sec=${call.request.num_rpcs}`);
|
||||||
callStatsTracker.getCallStats(call.request.num_rpcs, call.request.timeout_sec).then((value) => {
|
callStatsTracker.getCallStats(call.request.num_rpcs, call.request.timeout_sec).then((value) => {
|
||||||
|
console.log(`Sending stats response: ${JSON.stringify(value)}`);
|
||||||
callback(null, value);
|
callback(null, value);
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
callback({code: grpc.status.ABORTED, details: 'Call stats collection failed'});
|
callback({code: grpc.status.ABORTED, details: 'Call stats collection failed'});
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,14 @@ import { ConnectivityState } from './channel';
|
||||||
import { UnavailablePicker } from './picker';
|
import { UnavailablePicker } from './picker';
|
||||||
import { Status } from './constants';
|
import { Status } from './constants';
|
||||||
import { Metadata } from './metadata';
|
import { Metadata } from './metadata';
|
||||||
|
import * as logging from './logging';
|
||||||
|
import { LogVerbosity } from './constants';
|
||||||
|
|
||||||
|
const TRACER_NAME = 'cds_balancer';
|
||||||
|
|
||||||
|
function trace(text: string): void {
|
||||||
|
logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text);
|
||||||
|
}
|
||||||
|
|
||||||
const TYPE_NAME = 'cds';
|
const TYPE_NAME = 'cds';
|
||||||
|
|
||||||
|
|
@ -70,6 +78,7 @@ export class CdsLoadBalancer implements LoadBalancer {
|
||||||
* Otherwise, if the field is omitted, load reporting is disabled. */
|
* Otherwise, if the field is omitted, load reporting is disabled. */
|
||||||
edsConfig.lrsLoadReportingServerName = '';
|
edsConfig.lrsLoadReportingServerName = '';
|
||||||
}
|
}
|
||||||
|
trace('Child update EDS config: ' + JSON.stringify(edsConfig));
|
||||||
this.childBalancer.updateAddressList(
|
this.childBalancer.updateAddressList(
|
||||||
[],
|
[],
|
||||||
{ name: 'eds', eds: edsConfig },
|
{ name: 'eds', eds: edsConfig },
|
||||||
|
|
@ -82,6 +91,8 @@ export class CdsLoadBalancer implements LoadBalancer {
|
||||||
this.watcher
|
this.watcher
|
||||||
);
|
);
|
||||||
this.isWatcherActive = false;
|
this.isWatcherActive = false;
|
||||||
|
this.channelControlHelper.updateState(ConnectivityState.TRANSIENT_FAILURE, new UnavailablePicker({code: Status.UNAVAILABLE, details: 'CDS resource does not exist', metadata: new Metadata()}));
|
||||||
|
this.childBalancer.destroy();
|
||||||
},
|
},
|
||||||
onTransientError: (status) => {
|
onTransientError: (status) => {
|
||||||
if (this.latestCdsUpdate === null) {
|
if (this.latestCdsUpdate === null) {
|
||||||
|
|
@ -104,11 +115,14 @@ export class CdsLoadBalancer implements LoadBalancer {
|
||||||
attributes: { [key: string]: unknown }
|
attributes: { [key: string]: unknown }
|
||||||
): void {
|
): void {
|
||||||
if (!isCdsLoadBalancingConfig(lbConfig)) {
|
if (!isCdsLoadBalancingConfig(lbConfig)) {
|
||||||
|
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(attributes.xdsClient instanceof XdsClient)) {
|
if (!(attributes.xdsClient instanceof XdsClient)) {
|
||||||
|
trace('Discarding address list update missing xdsClient attribute');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
trace('Received update with config ' + JSON.stringify(lbConfig));
|
||||||
this.xdsClient = attributes.xdsClient;
|
this.xdsClient = attributes.xdsClient;
|
||||||
this.latestAttributes = attributes;
|
this.latestAttributes = attributes;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,9 +133,11 @@ export class ChildLoadBalancerHandler implements LoadBalancer {
|
||||||
destroy(): void {
|
destroy(): void {
|
||||||
if (this.currentChild) {
|
if (this.currentChild) {
|
||||||
this.currentChild.destroy();
|
this.currentChild.destroy();
|
||||||
|
this.currentChild = null;
|
||||||
}
|
}
|
||||||
if (this.pendingChild) {
|
if (this.pendingChild) {
|
||||||
this.pendingChild.destroy();
|
this.pendingChild.destroy();
|
||||||
|
this.pendingChild = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getTypeName(): string {
|
getTypeName(): string {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import {
|
||||||
registerLoadBalancerType,
|
registerLoadBalancerType,
|
||||||
getFirstUsableConfig,
|
getFirstUsableConfig,
|
||||||
} from './load-balancer';
|
} from './load-balancer';
|
||||||
import { SubchannelAddress } from './subchannel';
|
import { SubchannelAddress, subchannelAddressToString } from './subchannel';
|
||||||
import {
|
import {
|
||||||
LoadBalancingConfig,
|
LoadBalancingConfig,
|
||||||
isEdsLoadBalancingConfig,
|
isEdsLoadBalancingConfig,
|
||||||
|
|
@ -40,6 +40,14 @@ import { Locality__Output } from './generated/envoy/api/v2/core/Locality';
|
||||||
import { LocalitySubchannelAddress } from './load-balancer-priority';
|
import { LocalitySubchannelAddress } from './load-balancer-priority';
|
||||||
import { Status } from './constants';
|
import { Status } from './constants';
|
||||||
import { Metadata } from './metadata';
|
import { Metadata } from './metadata';
|
||||||
|
import * as logging from './logging';
|
||||||
|
import { LogVerbosity } from './constants';
|
||||||
|
|
||||||
|
const TRACER_NAME = 'eds_balancer';
|
||||||
|
|
||||||
|
function trace(text: string): void {
|
||||||
|
logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text);
|
||||||
|
}
|
||||||
|
|
||||||
const TYPE_NAME = 'eds';
|
const TYPE_NAME = 'eds';
|
||||||
|
|
||||||
|
|
@ -136,6 +144,8 @@ export class EdsLoadBalancer implements LoadBalancer {
|
||||||
this.watcher
|
this.watcher
|
||||||
);
|
);
|
||||||
this.isWatcherActive = false;
|
this.isWatcherActive = false;
|
||||||
|
this.channelControlHelper.updateState(ConnectivityState.TRANSIENT_FAILURE, new UnavailablePicker({code: Status.UNAVAILABLE, details: 'EDS resource does not exist', metadata: new Metadata()}));
|
||||||
|
this.childBalancer.destroy();
|
||||||
},
|
},
|
||||||
onTransientError: (status) => {
|
onTransientError: (status) => {
|
||||||
if (this.latestEdsUpdate === null) {
|
if (this.latestEdsUpdate === null) {
|
||||||
|
|
@ -356,6 +366,8 @@ export class EdsLoadBalancer implements LoadBalancer {
|
||||||
priorities: newPriorityNames.filter((value) => value !== undefined),
|
priorities: newPriorityNames.filter((value) => value !== undefined),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
trace('Child update addresses: ' + addressList.map(address => '(' + subchannelAddressToString(address) + ' path=' + address.localityPath + ')'));
|
||||||
|
trace('Child update service config: ' + JSON.stringify(childConfig));
|
||||||
this.childBalancer.updateAddressList(
|
this.childBalancer.updateAddressList(
|
||||||
addressList,
|
addressList,
|
||||||
childConfig,
|
childConfig,
|
||||||
|
|
@ -372,11 +384,14 @@ export class EdsLoadBalancer implements LoadBalancer {
|
||||||
attributes: { [key: string]: unknown }
|
attributes: { [key: string]: unknown }
|
||||||
): void {
|
): void {
|
||||||
if (!isEdsLoadBalancingConfig(lbConfig)) {
|
if (!isEdsLoadBalancingConfig(lbConfig)) {
|
||||||
|
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(attributes.xdsClient instanceof XdsClient)) {
|
if (!(attributes.xdsClient instanceof XdsClient)) {
|
||||||
|
trace('Discarding address list update missing xdsClient attribute');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
trace('Received update with config: ' + JSON.stringify(lbConfig));
|
||||||
this.lastestConfig = lbConfig;
|
this.lastestConfig = lbConfig;
|
||||||
this.latestAttributes = attributes;
|
this.latestAttributes = attributes;
|
||||||
this.xdsClient = attributes.xdsClient;
|
this.xdsClient = attributes.xdsClient;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import {
|
||||||
getFirstUsableConfig,
|
getFirstUsableConfig,
|
||||||
registerLoadBalancerType,
|
registerLoadBalancerType,
|
||||||
} from './load-balancer';
|
} from './load-balancer';
|
||||||
import { SubchannelAddress } from './subchannel';
|
import { SubchannelAddress, subchannelAddressToString } from './subchannel';
|
||||||
import {
|
import {
|
||||||
LoadBalancingConfig,
|
LoadBalancingConfig,
|
||||||
isPriorityLoadBalancingConfig,
|
isPriorityLoadBalancingConfig,
|
||||||
|
|
@ -32,6 +32,14 @@ import { ChildLoadBalancerHandler } from './load-balancer-child-handler';
|
||||||
import { ChannelOptions } from './channel-options';
|
import { ChannelOptions } from './channel-options';
|
||||||
import { Status } from './constants';
|
import { Status } from './constants';
|
||||||
import { Metadata } from './metadata';
|
import { Metadata } from './metadata';
|
||||||
|
import * as logging from './logging';
|
||||||
|
import { LogVerbosity } from './constants';
|
||||||
|
|
||||||
|
const TRACER_NAME = 'priority';
|
||||||
|
|
||||||
|
function trace(text: string): void {
|
||||||
|
logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text);
|
||||||
|
}
|
||||||
|
|
||||||
const TYPE_NAME = 'priority';
|
const TYPE_NAME = 'priority';
|
||||||
|
|
||||||
|
|
@ -222,6 +230,10 @@ export class PriorityLoadBalancer implements LoadBalancer {
|
||||||
constructor(private channelControlHelper: ChannelControlHelper) {}
|
constructor(private channelControlHelper: ChannelControlHelper) {}
|
||||||
|
|
||||||
private updateState(state: ConnectivityState, picker: Picker) {
|
private updateState(state: ConnectivityState, picker: Picker) {
|
||||||
|
trace(
|
||||||
|
'Transitioning to ' +
|
||||||
|
ConnectivityState[state]
|
||||||
|
);
|
||||||
/* If switching to IDLE, use a QueuePicker attached to this load balancer
|
/* If switching to IDLE, use a QueuePicker attached to this load balancer
|
||||||
* so that when the picker calls exitIdle, that in turn calls exitIdle on
|
* so that when the picker calls exitIdle, that in turn calls exitIdle on
|
||||||
* the PriorityChildImpl, which will start the failover timer. */
|
* the PriorityChildImpl, which will start the failover timer. */
|
||||||
|
|
@ -233,6 +245,7 @@ export class PriorityLoadBalancer implements LoadBalancer {
|
||||||
|
|
||||||
private onChildStateChange(child: PriorityChildBalancer) {
|
private onChildStateChange(child: PriorityChildBalancer) {
|
||||||
const childState = child.getConnectivityState();
|
const childState = child.getConnectivityState();
|
||||||
|
trace('Child ' + child.getName() + ' transitioning to ' + ConnectivityState[childState]);
|
||||||
if (child === this.currentChildFromBeforeUpdate) {
|
if (child === this.currentChildFromBeforeUpdate) {
|
||||||
if (
|
if (
|
||||||
childState === ConnectivityState.READY ||
|
childState === ConnectivityState.READY ||
|
||||||
|
|
@ -369,6 +382,7 @@ export class PriorityLoadBalancer implements LoadBalancer {
|
||||||
): void {
|
): void {
|
||||||
if (!isPriorityLoadBalancingConfig(lbConfig)) {
|
if (!isPriorityLoadBalancingConfig(lbConfig)) {
|
||||||
// Reject a config of the wrong type
|
// Reject a config of the wrong type
|
||||||
|
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const priorityConfig = lbConfig.priority;
|
const priorityConfig = lbConfig.priority;
|
||||||
|
|
@ -416,6 +430,7 @@ export class PriorityLoadBalancer implements LoadBalancer {
|
||||||
const chosenChildConfig = getFirstUsableConfig(childConfig.config);
|
const chosenChildConfig = getFirstUsableConfig(childConfig.config);
|
||||||
if (chosenChildConfig !== null) {
|
if (chosenChildConfig !== null) {
|
||||||
const childAddresses = childAddressMap.get(childName) ?? [];
|
const childAddresses = childAddressMap.get(childName) ?? [];
|
||||||
|
trace('Assigning child ' + childName + ' address list ' + childAddresses.map(address => '(' + subchannelAddressToString(address) + ' path=' + address.localityPath + ')'))
|
||||||
this.latestUpdates.set(childName, {
|
this.latestUpdates.set(childName, {
|
||||||
subchannelAddress: childAddresses,
|
subchannelAddress: childAddresses,
|
||||||
lbConfig: chosenChildConfig,
|
lbConfig: chosenChildConfig,
|
||||||
|
|
@ -433,6 +448,7 @@ export class PriorityLoadBalancer implements LoadBalancer {
|
||||||
// Deactivate all children that are no longer in the priority list
|
// Deactivate all children that are no longer in the priority list
|
||||||
for (const [childName, child] of this.children) {
|
for (const [childName, child] of this.children) {
|
||||||
if (this.priorities.indexOf(childName) < 0) {
|
if (this.priorities.indexOf(childName) < 0) {
|
||||||
|
trace('Deactivating child ' + childName);
|
||||||
child.deactivate();
|
child.deactivate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { LoadBalancer, ChannelControlHelper, getFirstUsableConfig, registerLoadBalancerType } from "./load-balancer";
|
import { LoadBalancer, ChannelControlHelper, getFirstUsableConfig, registerLoadBalancerType } from "./load-balancer";
|
||||||
import { SubchannelAddress } from "./subchannel";
|
import { SubchannelAddress, subchannelAddressToString } from "./subchannel";
|
||||||
import { LoadBalancingConfig, WeightedTarget, isWeightedTargetLoadBalancingConfig } from "./load-balancing-config";
|
import { LoadBalancingConfig, WeightedTarget, isWeightedTargetLoadBalancingConfig } from "./load-balancing-config";
|
||||||
import { Picker, PickResult, PickArgs, QueuePicker, UnavailablePicker } from "./picker";
|
import { Picker, PickResult, PickArgs, QueuePicker, UnavailablePicker } from "./picker";
|
||||||
import { ConnectivityState } from "./channel";
|
import { ConnectivityState } from "./channel";
|
||||||
|
|
@ -24,6 +24,14 @@ import { ChildLoadBalancerHandler } from "./load-balancer-child-handler";
|
||||||
import { Status } from "./constants";
|
import { Status } from "./constants";
|
||||||
import { Metadata } from "./metadata";
|
import { Metadata } from "./metadata";
|
||||||
import { isLocalitySubchannelAddress, LocalitySubchannelAddress } from "./load-balancer-priority";
|
import { isLocalitySubchannelAddress, LocalitySubchannelAddress } from "./load-balancer-priority";
|
||||||
|
import * as logging from './logging';
|
||||||
|
import { LogVerbosity } from './constants';
|
||||||
|
|
||||||
|
const TRACER_NAME = 'weighted_target';
|
||||||
|
|
||||||
|
function trace(text: string): void {
|
||||||
|
logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text);
|
||||||
|
}
|
||||||
|
|
||||||
const TYPE_NAME = 'weighted_target';
|
const TYPE_NAME = 'weighted_target';
|
||||||
|
|
||||||
|
|
@ -116,6 +124,7 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateState(connectivityState: ConnectivityState, picker: Picker) {
|
private updateState(connectivityState: ConnectivityState, picker: Picker) {
|
||||||
|
trace('Target ' + this.name + ' ' + ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[connectivityState]);
|
||||||
this.connectivityState = connectivityState;
|
this.connectivityState = connectivityState;
|
||||||
this.picker = picker;
|
this.picker = picker;
|
||||||
this.parent.updateState();
|
this.parent.updateState();
|
||||||
|
|
@ -239,12 +248,17 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
|
||||||
metadata: new Metadata()
|
metadata: new Metadata()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
trace(
|
||||||
|
'Transitioning to ' +
|
||||||
|
ConnectivityState[connectivityState]
|
||||||
|
);
|
||||||
this.channelControlHelper.updateState(connectivityState, picker);
|
this.channelControlHelper.updateState(connectivityState, picker);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAddressList(addressList: SubchannelAddress[], lbConfig: LoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
updateAddressList(addressList: SubchannelAddress[], lbConfig: LoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
||||||
if (!isWeightedTargetLoadBalancingConfig(lbConfig)) {
|
if (!isWeightedTargetLoadBalancingConfig(lbConfig)) {
|
||||||
// Reject a config of the wrong type
|
// Reject a config of the wrong type
|
||||||
|
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,7 +266,7 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
|
||||||
* which child it belongs to. So we bucket those addresses by that first
|
* which child it belongs to. So we bucket those addresses by that first
|
||||||
* element, and pass along the rest of the localityPath for that child
|
* element, and pass along the rest of the localityPath for that child
|
||||||
* to use. */
|
* to use. */
|
||||||
const childAddressMap = new Map<string, SubchannelAddress[]>();
|
const childAddressMap = new Map<string, LocalitySubchannelAddress[]>();
|
||||||
for (const address of addressList) {
|
for (const address of addressList) {
|
||||||
if (!isLocalitySubchannelAddress(address)) {
|
if (!isLocalitySubchannelAddress(address)) {
|
||||||
// Reject address that cannot be associated with targets
|
// Reject address that cannot be associated with targets
|
||||||
|
|
@ -284,12 +298,15 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
|
||||||
} else {
|
} else {
|
||||||
target.maybeReactivate();
|
target.maybeReactivate();
|
||||||
}
|
}
|
||||||
target.updateAddressList(childAddressMap.get(targetName) ?? [], targetConfig, attributes);
|
const targetAddresses = childAddressMap.get(targetName) ?? [];
|
||||||
|
trace('Assigning target ' + targetName + ' address list ' + targetAddresses.map(address => '(' + subchannelAddressToString(address) + ' path=' + address.localityPath + ')'));
|
||||||
|
target.updateAddressList(targetAddresses, targetConfig, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deactivate targets that are not in the new config
|
// Deactivate targets that are not in the new config
|
||||||
for (const [targetName, target] of this.targets) {
|
for (const [targetName, target] of this.targets) {
|
||||||
if (this.targetList.indexOf(targetName) < 0) {
|
if (this.targetList.indexOf(targetName) < 0) {
|
||||||
|
trace('Deactivating target ' + targetName);
|
||||||
target.deactivate();
|
target.deactivate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,16 @@ import { GrpcUri, uriToString } from './uri-parser';
|
||||||
import { XdsClient } from './xds-client';
|
import { XdsClient } from './xds-client';
|
||||||
import { ServiceConfig } from './service-config';
|
import { ServiceConfig } from './service-config';
|
||||||
import { StatusObject } from './call-stream';
|
import { StatusObject } from './call-stream';
|
||||||
import { Status } from './constants';
|
import { Status, LogVerbosity } from './constants';
|
||||||
import { Metadata } from './metadata';
|
import { Metadata } from './metadata';
|
||||||
import { ChannelOptions } from './channel-options';
|
import { ChannelOptions } from './channel-options';
|
||||||
|
import * as logging from './logging';
|
||||||
|
|
||||||
|
const TRACER_NAME = 'xds_resolver';
|
||||||
|
|
||||||
|
function trace(text: string): void {
|
||||||
|
logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text);
|
||||||
|
}
|
||||||
|
|
||||||
class XdsResolver implements Resolver {
|
class XdsResolver implements Resolver {
|
||||||
private resolutionStarted = false;
|
private resolutionStarted = false;
|
||||||
|
|
@ -47,10 +54,12 @@ class XdsResolver implements Resolver {
|
||||||
// Wait until updateResolution is called once to start the xDS requests
|
// Wait until updateResolution is called once to start the xDS requests
|
||||||
if (!this.resolutionStarted) {
|
if (!this.resolutionStarted) {
|
||||||
this.resolutionStarted = true;
|
this.resolutionStarted = true;
|
||||||
|
trace('Starting resolution for target ' + this.target);
|
||||||
const xdsClient = new XdsClient(
|
const xdsClient = new XdsClient(
|
||||||
this.target.path,
|
this.target.path,
|
||||||
{
|
{
|
||||||
onValidUpdate: (update: ServiceConfig) => {
|
onValidUpdate: (update: ServiceConfig) => {
|
||||||
|
trace('Resolved service config for target ' + this.target + ': ' + JSON.stringify(update));
|
||||||
this.hasReportedSuccess = true;
|
this.hasReportedSuccess = true;
|
||||||
this.listener.onSuccessfulResolution([], update, null, {
|
this.listener.onSuccessfulResolution([], update, null, {
|
||||||
xdsClient: xdsClient,
|
xdsClient: xdsClient,
|
||||||
|
|
@ -60,10 +69,12 @@ class XdsResolver implements Resolver {
|
||||||
/* A transient error only needs to bubble up as a failure if we have
|
/* A transient error only needs to bubble up as a failure if we have
|
||||||
* not already provided a ServiceConfig for the upper layer to use */
|
* not already provided a ServiceConfig for the upper layer to use */
|
||||||
if (!this.hasReportedSuccess) {
|
if (!this.hasReportedSuccess) {
|
||||||
|
trace('Resolution error for target ' + this.target + ' due to xDS client transient error ' + error.details);
|
||||||
this.reportResolutionError();
|
this.reportResolutionError();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onResourceDoesNotExist: () => {
|
onResourceDoesNotExist: () => {
|
||||||
|
trace('Resolution error for target ' + this.target + ': resource does not exist');
|
||||||
this.reportResolutionError();
|
this.reportResolutionError();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue