mirror of https://github.com/grpc/grpc-node.git
grpc-js-xds: Update LB policies to handle grpc-js changes
This commit is contained in:
parent
49b7c6af34
commit
e919aa7aa3
|
@ -34,7 +34,7 @@ import TypedLoadBalancingConfig = grpc.experimental.TypedLoadBalancingConfig;
|
||||||
import LoadBalancer = grpc.experimental.LoadBalancer;
|
import LoadBalancer = grpc.experimental.LoadBalancer;
|
||||||
import ChannelControlHelper = grpc.experimental.ChannelControlHelper;
|
import ChannelControlHelper = grpc.experimental.ChannelControlHelper;
|
||||||
import ChildLoadBalancerHandler = grpc.experimental.ChildLoadBalancerHandler;
|
import ChildLoadBalancerHandler = grpc.experimental.ChildLoadBalancerHandler;
|
||||||
import SubchannelAddress = grpc.experimental.SubchannelAddress;
|
import Endpoint = grpc.experimental.Endpoint;
|
||||||
import Picker = grpc.experimental.Picker;
|
import Picker = grpc.experimental.Picker;
|
||||||
import PickArgs = grpc.experimental.PickArgs;
|
import PickArgs = grpc.experimental.PickArgs;
|
||||||
import PickResult = grpc.experimental.PickResult;
|
import PickResult = grpc.experimental.PickResult;
|
||||||
|
@ -99,12 +99,12 @@ class RpcBehaviorLoadBalancer implements LoadBalancer {
|
||||||
});
|
});
|
||||||
this.child = new ChildLoadBalancerHandler(childChannelControlHelper);
|
this.child = new ChildLoadBalancerHandler(childChannelControlHelper);
|
||||||
}
|
}
|
||||||
updateAddressList(addressList: SubchannelAddress[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
||||||
if (!(lbConfig instanceof RpcBehaviorLoadBalancingConfig)) {
|
if (!(lbConfig instanceof RpcBehaviorLoadBalancingConfig)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.latestConfig = lbConfig;
|
this.latestConfig = lbConfig;
|
||||||
this.child.updateAddressList(addressList, RPC_BEHAVIOR_CHILD_CONFIG, attributes);
|
this.child.updateAddressList(endpointList, RPC_BEHAVIOR_CHILD_CONFIG, attributes);
|
||||||
}
|
}
|
||||||
exitIdle(): void {
|
exitIdle(): void {
|
||||||
this.child.exitIdle();
|
this.child.exitIdle();
|
||||||
|
|
|
@ -18,23 +18,16 @@
|
||||||
import { connectivityState, status, Metadata, logVerbosity, experimental, LoadBalancingConfig } from '@grpc/grpc-js';
|
import { connectivityState, status, Metadata, logVerbosity, experimental, LoadBalancingConfig } from '@grpc/grpc-js';
|
||||||
import { getSingletonXdsClient, Watcher, XdsClient } from './xds-client';
|
import { getSingletonXdsClient, Watcher, XdsClient } from './xds-client';
|
||||||
import { Cluster__Output } from './generated/envoy/config/cluster/v3/Cluster';
|
import { Cluster__Output } from './generated/envoy/config/cluster/v3/Cluster';
|
||||||
import SubchannelAddress = experimental.SubchannelAddress;
|
import Endpoint = experimental.Endpoint;
|
||||||
import UnavailablePicker = experimental.UnavailablePicker;
|
import UnavailablePicker = experimental.UnavailablePicker;
|
||||||
import ChildLoadBalancerHandler = experimental.ChildLoadBalancerHandler;
|
import ChildLoadBalancerHandler = experimental.ChildLoadBalancerHandler;
|
||||||
import LoadBalancer = experimental.LoadBalancer;
|
import LoadBalancer = experimental.LoadBalancer;
|
||||||
import ChannelControlHelper = experimental.ChannelControlHelper;
|
import ChannelControlHelper = experimental.ChannelControlHelper;
|
||||||
import registerLoadBalancerType = experimental.registerLoadBalancerType;
|
import registerLoadBalancerType = experimental.registerLoadBalancerType;
|
||||||
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
|
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
|
||||||
import SuccessRateEjectionConfig = experimental.SuccessRateEjectionConfig;
|
|
||||||
import FailurePercentageEjectionConfig = experimental.FailurePercentageEjectionConfig;
|
|
||||||
import QueuePicker = experimental.QueuePicker;
|
import QueuePicker = experimental.QueuePicker;
|
||||||
import OutlierDetectionRawConfig = experimental.OutlierDetectionRawConfig;
|
|
||||||
import parseLoadBalancingConfig = experimental.parseLoadBalancingConfig;
|
import parseLoadBalancingConfig = experimental.parseLoadBalancingConfig;
|
||||||
import { OutlierDetection__Output } from './generated/envoy/config/cluster/v3/OutlierDetection';
|
|
||||||
import { Duration__Output } from './generated/google/protobuf/Duration';
|
|
||||||
import { EXPERIMENTAL_OUTLIER_DETECTION } from './environment';
|
|
||||||
import { DiscoveryMechanism, XdsClusterResolverChildPolicyHandler } from './load-balancer-xds-cluster-resolver';
|
import { DiscoveryMechanism, XdsClusterResolverChildPolicyHandler } from './load-balancer-xds-cluster-resolver';
|
||||||
import { CLUSTER_CONFIG_TYPE_URL, decodeSingleResource } from './resources';
|
|
||||||
import { CdsUpdate, ClusterResourceType } from './xds-resource-type/cluster-resource-type';
|
import { CdsUpdate, ClusterResourceType } from './xds-resource-type/cluster-resource-type';
|
||||||
|
|
||||||
const TRACER_NAME = 'cds_balancer';
|
const TRACER_NAME = 'cds_balancer';
|
||||||
|
@ -258,7 +251,7 @@ export class CdsLoadBalancer implements LoadBalancer {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAddressList(
|
updateAddressList(
|
||||||
addressList: SubchannelAddress[],
|
endpointList: Endpoint[],
|
||||||
lbConfig: TypedLoadBalancingConfig,
|
lbConfig: TypedLoadBalancingConfig,
|
||||||
attributes: { [key: string]: unknown }
|
attributes: { [key: string]: unknown }
|
||||||
): void {
|
): void {
|
||||||
|
|
|
@ -19,8 +19,8 @@ import { connectivityState as ConnectivityState, status as Status, Metadata, log
|
||||||
import LoadBalancer = experimental.LoadBalancer;
|
import LoadBalancer = experimental.LoadBalancer;
|
||||||
import ChannelControlHelper = experimental.ChannelControlHelper;
|
import ChannelControlHelper = experimental.ChannelControlHelper;
|
||||||
import registerLoadBalancerType = experimental.registerLoadBalancerType;
|
import registerLoadBalancerType = experimental.registerLoadBalancerType;
|
||||||
import SubchannelAddress = experimental.SubchannelAddress;
|
import Endpoint = experimental.Endpoint;
|
||||||
import subchannelAddressToString = experimental.subchannelAddressToString;
|
import endpointToString = experimental.endpointToString;
|
||||||
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
|
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
|
||||||
import Picker = experimental.Picker;
|
import Picker = experimental.Picker;
|
||||||
import QueuePicker = experimental.QueuePicker;
|
import QueuePicker = experimental.QueuePicker;
|
||||||
|
@ -40,16 +40,16 @@ const TYPE_NAME = 'priority';
|
||||||
const DEFAULT_FAILOVER_TIME_MS = 10_000;
|
const DEFAULT_FAILOVER_TIME_MS = 10_000;
|
||||||
const DEFAULT_RETENTION_INTERVAL_MS = 15 * 60 * 1000;
|
const DEFAULT_RETENTION_INTERVAL_MS = 15 * 60 * 1000;
|
||||||
|
|
||||||
export type LocalitySubchannelAddress = SubchannelAddress & {
|
export interface LocalityEndpoint extends Endpoint {
|
||||||
localityPath: string[];
|
localityPath: string[];
|
||||||
locality: Locality__Output;
|
locality: Locality__Output;
|
||||||
weight: number;
|
weight: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function isLocalitySubchannelAddress(
|
export function isLocalityEndpoint(
|
||||||
address: SubchannelAddress
|
address: Endpoint
|
||||||
): address is LocalitySubchannelAddress {
|
): address is LocalityEndpoint {
|
||||||
return Array.isArray((address as LocalitySubchannelAddress).localityPath);
|
return Array.isArray((address as LocalityEndpoint).localityPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,7 +138,7 @@ class PriorityLoadBalancingConfig implements TypedLoadBalancingConfig {
|
||||||
|
|
||||||
interface PriorityChildBalancer {
|
interface PriorityChildBalancer {
|
||||||
updateAddressList(
|
updateAddressList(
|
||||||
addressList: SubchannelAddress[],
|
endpointList: Endpoint[],
|
||||||
lbConfig: TypedLoadBalancingConfig,
|
lbConfig: TypedLoadBalancingConfig,
|
||||||
attributes: { [key: string]: unknown }
|
attributes: { [key: string]: unknown }
|
||||||
): void;
|
): void;
|
||||||
|
@ -154,7 +154,7 @@ interface PriorityChildBalancer {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UpdateArgs {
|
interface UpdateArgs {
|
||||||
subchannelAddress: SubchannelAddress[];
|
subchannelAddress: Endpoint[];
|
||||||
lbConfig: TypedLoadBalancingConfig;
|
lbConfig: TypedLoadBalancingConfig;
|
||||||
ignoreReresolutionRequests: boolean;
|
ignoreReresolutionRequests: boolean;
|
||||||
}
|
}
|
||||||
|
@ -218,11 +218,11 @@ export class PriorityLoadBalancer implements LoadBalancer {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAddressList(
|
updateAddressList(
|
||||||
addressList: SubchannelAddress[],
|
endpointList: Endpoint[],
|
||||||
lbConfig: TypedLoadBalancingConfig,
|
lbConfig: TypedLoadBalancingConfig,
|
||||||
attributes: { [key: string]: unknown }
|
attributes: { [key: string]: unknown }
|
||||||
): void {
|
): void {
|
||||||
this.childBalancer.updateAddressList(addressList, lbConfig, attributes);
|
this.childBalancer.updateAddressList(endpointList, lbConfig, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
exitIdle() {
|
exitIdle() {
|
||||||
|
@ -412,7 +412,7 @@ export class PriorityLoadBalancer implements LoadBalancer {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAddressList(
|
updateAddressList(
|
||||||
addressList: SubchannelAddress[],
|
endpointList: Endpoint[],
|
||||||
lbConfig: TypedLoadBalancingConfig,
|
lbConfig: TypedLoadBalancingConfig,
|
||||||
attributes: { [key: string]: unknown }
|
attributes: { [key: string]: unknown }
|
||||||
): void {
|
): void {
|
||||||
|
@ -425,23 +425,23 @@ export class PriorityLoadBalancer 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: Map<string, LocalitySubchannelAddress[]> = new Map<
|
const childAddressMap: Map<string, LocalityEndpoint[]> = new Map<
|
||||||
string,
|
string,
|
||||||
LocalitySubchannelAddress[]
|
LocalityEndpoint[]
|
||||||
>();
|
>();
|
||||||
for (const address of addressList) {
|
for (const endpoint of endpointList) {
|
||||||
if (!isLocalitySubchannelAddress(address)) {
|
if (!isLocalityEndpoint(endpoint)) {
|
||||||
// Reject address that cannot be prioritized
|
// Reject address that cannot be prioritized
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (address.localityPath.length < 1) {
|
if (endpoint.localityPath.length < 1) {
|
||||||
// Reject address that cannot be prioritized
|
// Reject address that cannot be prioritized
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const childName = address.localityPath[0];
|
const childName = endpoint.localityPath[0];
|
||||||
const childAddress: LocalitySubchannelAddress = {
|
const childAddress: LocalityEndpoint = {
|
||||||
...address,
|
...endpoint,
|
||||||
localityPath: address.localityPath.slice(1),
|
localityPath: endpoint.localityPath.slice(1),
|
||||||
};
|
};
|
||||||
let childAddressList = childAddressMap.get(childName);
|
let childAddressList = childAddressMap.get(childName);
|
||||||
if (childAddressList === undefined) {
|
if (childAddressList === undefined) {
|
||||||
|
@ -458,7 +458,7 @@ export class PriorityLoadBalancer implements LoadBalancer {
|
||||||
* update all existing children with their new configs */
|
* update all existing children with their new configs */
|
||||||
for (const [childName, childConfig] of lbConfig.getChildren()) {
|
for (const [childName, childConfig] of lbConfig.getChildren()) {
|
||||||
const childAddresses = childAddressMap.get(childName) ?? [];
|
const childAddresses = childAddressMap.get(childName) ?? [];
|
||||||
trace('Assigning child ' + childName + ' address list ' + childAddresses.map(address => '(' + subchannelAddressToString(address) + ' path=' + address.localityPath + ')'))
|
trace('Assigning child ' + childName + ' endpoint list ' + childAddresses.map(endpoint => '(' + endpointToString(endpoint) + ' path=' + endpoint.localityPath + ')'))
|
||||||
this.latestUpdates.set(childName, {
|
this.latestUpdates.set(childName, {
|
||||||
subchannelAddress: childAddresses,
|
subchannelAddress: childAddresses,
|
||||||
lbConfig: childConfig.config,
|
lbConfig: childConfig.config,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity, experimental, LoadBalancingConfig } from "@grpc/grpc-js";
|
import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity, experimental, LoadBalancingConfig } from "@grpc/grpc-js";
|
||||||
import { isLocalitySubchannelAddress, LocalitySubchannelAddress } from "./load-balancer-priority";
|
import { isLocalityEndpoint, LocalityEndpoint } from "./load-balancer-priority";
|
||||||
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
|
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
|
||||||
import LoadBalancer = experimental.LoadBalancer;
|
import LoadBalancer = experimental.LoadBalancer;
|
||||||
import ChannelControlHelper = experimental.ChannelControlHelper;
|
import ChannelControlHelper = experimental.ChannelControlHelper;
|
||||||
|
@ -27,8 +27,8 @@ import PickResult = experimental.PickResult;
|
||||||
import PickArgs = experimental.PickArgs;
|
import PickArgs = experimental.PickArgs;
|
||||||
import QueuePicker = experimental.QueuePicker;
|
import QueuePicker = experimental.QueuePicker;
|
||||||
import UnavailablePicker = experimental.UnavailablePicker;
|
import UnavailablePicker = experimental.UnavailablePicker;
|
||||||
import SubchannelAddress = experimental.SubchannelAddress;
|
import Endpoint = experimental.Endpoint;
|
||||||
import subchannelAddressToString = experimental.subchannelAddressToString;
|
import endpointToString = experimental.endpointToString;
|
||||||
import selectLbConfigFromList = experimental.selectLbConfigFromList;
|
import selectLbConfigFromList = experimental.selectLbConfigFromList;
|
||||||
|
|
||||||
const TRACER_NAME = 'weighted_target';
|
const TRACER_NAME = 'weighted_target';
|
||||||
|
@ -154,7 +154,7 @@ class WeightedTargetPicker implements Picker {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface WeightedChild {
|
interface WeightedChild {
|
||||||
updateAddressList(addressList: SubchannelAddress[], lbConfig: WeightedTarget, attributes: { [key: string]: unknown; }): void;
|
updateAddressList(endpointList: Endpoint[], lbConfig: WeightedTarget, attributes: { [key: string]: unknown; }): void;
|
||||||
exitIdle(): void;
|
exitIdle(): void;
|
||||||
resetBackoff(): void;
|
resetBackoff(): void;
|
||||||
destroy(): void;
|
destroy(): void;
|
||||||
|
@ -190,9 +190,9 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
|
||||||
this.parent.maybeUpdateState();
|
this.parent.maybeUpdateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAddressList(addressList: SubchannelAddress[], lbConfig: WeightedTarget, attributes: { [key: string]: unknown; }): void {
|
updateAddressList(endpointList: Endpoint[], lbConfig: WeightedTarget, attributes: { [key: string]: unknown; }): void {
|
||||||
this.weight = lbConfig.weight;
|
this.weight = lbConfig.weight;
|
||||||
this.childBalancer.updateAddressList(addressList, lbConfig.child_policy, attributes);
|
this.childBalancer.updateAddressList(endpointList, lbConfig.child_policy, attributes);
|
||||||
}
|
}
|
||||||
exitIdle(): void {
|
exitIdle(): void {
|
||||||
this.childBalancer.exitIdle();
|
this.childBalancer.exitIdle();
|
||||||
|
@ -319,7 +319,7 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
|
||||||
this.channelControlHelper.updateState(connectivityState, picker);
|
this.channelControlHelper.updateState(connectivityState, picker);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAddressList(addressList: SubchannelAddress[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
updateAddressList(addressList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
||||||
if (!(lbConfig instanceof WeightedTargetLoadBalancingConfig)) {
|
if (!(lbConfig instanceof WeightedTargetLoadBalancingConfig)) {
|
||||||
// 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.toJsonObject(), undefined, 2));
|
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig.toJsonObject(), undefined, 2));
|
||||||
|
@ -330,9 +330,9 @@ 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, LocalitySubchannelAddress[]>();
|
const childEndpointMap = new Map<string, LocalityEndpoint[]>();
|
||||||
for (const address of addressList) {
|
for (const address of addressList) {
|
||||||
if (!isLocalitySubchannelAddress(address)) {
|
if (!isLocalityEndpoint(address)) {
|
||||||
// Reject address that cannot be associated with targets
|
// Reject address that cannot be associated with targets
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -341,14 +341,14 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const childName = address.localityPath[0];
|
const childName = address.localityPath[0];
|
||||||
const childAddress: LocalitySubchannelAddress = {
|
const childAddress: LocalityEndpoint = {
|
||||||
...address,
|
...address,
|
||||||
localityPath: address.localityPath.slice(1),
|
localityPath: address.localityPath.slice(1),
|
||||||
};
|
};
|
||||||
let childAddressList = childAddressMap.get(childName);
|
let childAddressList = childEndpointMap.get(childName);
|
||||||
if (childAddressList === undefined) {
|
if (childAddressList === undefined) {
|
||||||
childAddressList = [];
|
childAddressList = [];
|
||||||
childAddressMap.set(childName, childAddressList);
|
childEndpointMap.set(childName, childAddressList);
|
||||||
}
|
}
|
||||||
childAddressList.push(childAddress);
|
childAddressList.push(childAddress);
|
||||||
}
|
}
|
||||||
|
@ -363,9 +363,9 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
|
||||||
} else {
|
} else {
|
||||||
target.maybeReactivate();
|
target.maybeReactivate();
|
||||||
}
|
}
|
||||||
const targetAddresses = childAddressMap.get(targetName) ?? [];
|
const targetEndpoints = childEndpointMap.get(targetName) ?? [];
|
||||||
trace('Assigning target ' + targetName + ' address list ' + targetAddresses.map(address => '(' + subchannelAddressToString(address) + ' path=' + address.localityPath + ')'));
|
trace('Assigning target ' + targetName + ' address list ' + targetEndpoints.map(endpoint => '(' + endpointToString(endpoint) + ' path=' + endpoint.localityPath + ')'));
|
||||||
target.updateAddressList(targetAddresses, targetConfig, attributes);
|
target.updateAddressList(targetEndpoints, targetConfig, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deactivate targets that are not in the new config
|
// Deactivate targets that are not in the new config
|
||||||
|
|
|
@ -18,11 +18,13 @@
|
||||||
import { experimental, logVerbosity, status as Status, Metadata, connectivityState } from "@grpc/grpc-js";
|
import { experimental, logVerbosity, status as Status, Metadata, connectivityState } from "@grpc/grpc-js";
|
||||||
import { validateXdsServerConfig, XdsServerConfig } from "./xds-bootstrap";
|
import { validateXdsServerConfig, XdsServerConfig } from "./xds-bootstrap";
|
||||||
import { getSingletonXdsClient, XdsClient, XdsClusterDropStats, XdsClusterLocalityStats } from "./xds-client";
|
import { getSingletonXdsClient, XdsClient, XdsClusterDropStats, XdsClusterLocalityStats } from "./xds-client";
|
||||||
import { LocalitySubchannelAddress } from "./load-balancer-priority";
|
import { LocalityEndpoint } from "./load-balancer-priority";
|
||||||
|
|
||||||
import LoadBalancer = experimental.LoadBalancer;
|
import LoadBalancer = experimental.LoadBalancer;
|
||||||
import registerLoadBalancerType = experimental.registerLoadBalancerType;
|
import registerLoadBalancerType = experimental.registerLoadBalancerType;
|
||||||
import SubchannelAddress = experimental.SubchannelAddress;
|
import Endpoint = experimental.Endpoint;
|
||||||
|
import endpointHasAddress = experimental.endpointHasAddress;
|
||||||
|
import subchannelAddressToString = experimental.subchannelAddressToString;
|
||||||
import Picker = experimental.Picker;
|
import Picker = experimental.Picker;
|
||||||
import PickArgs = experimental.PickArgs;
|
import PickArgs = experimental.PickArgs;
|
||||||
import PickResult = experimental.PickResult;
|
import PickResult = experimental.PickResult;
|
||||||
|
@ -34,6 +36,7 @@ import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
|
||||||
import selectLbConfigFromList = experimental.selectLbConfigFromList;
|
import selectLbConfigFromList = experimental.selectLbConfigFromList;
|
||||||
import SubchannelInterface = experimental.SubchannelInterface;
|
import SubchannelInterface = experimental.SubchannelInterface;
|
||||||
import BaseSubchannelWrapper = experimental.BaseSubchannelWrapper;
|
import BaseSubchannelWrapper = experimental.BaseSubchannelWrapper;
|
||||||
|
import { Locality__Output } from "./generated/envoy/config/core/v3/Locality";
|
||||||
|
|
||||||
const TRACER_NAME = 'xds_cluster_impl';
|
const TRACER_NAME = 'xds_cluster_impl';
|
||||||
|
|
||||||
|
@ -245,6 +248,7 @@ function getCallCounterMapKey(cluster: string, edsServiceName?: string): string
|
||||||
|
|
||||||
class XdsClusterImplBalancer implements LoadBalancer {
|
class XdsClusterImplBalancer implements LoadBalancer {
|
||||||
private childBalancer: ChildLoadBalancerHandler;
|
private childBalancer: ChildLoadBalancerHandler;
|
||||||
|
private lastestEndpointList: Endpoint[] | null = null;
|
||||||
private latestConfig: XdsClusterImplLoadBalancingConfig | null = null;
|
private latestConfig: XdsClusterImplLoadBalancingConfig | null = null;
|
||||||
private clusterDropStats: XdsClusterDropStats | null = null;
|
private clusterDropStats: XdsClusterDropStats | null = null;
|
||||||
private xdsClient: XdsClient | null = null;
|
private xdsClient: XdsClient | null = null;
|
||||||
|
@ -252,11 +256,20 @@ class XdsClusterImplBalancer implements LoadBalancer {
|
||||||
constructor(private readonly channelControlHelper: ChannelControlHelper) {
|
constructor(private readonly channelControlHelper: ChannelControlHelper) {
|
||||||
this.childBalancer = new ChildLoadBalancerHandler(createChildChannelControlHelper(channelControlHelper, {
|
this.childBalancer = new ChildLoadBalancerHandler(createChildChannelControlHelper(channelControlHelper, {
|
||||||
createSubchannel: (subchannelAddress, subchannelArgs) => {
|
createSubchannel: (subchannelAddress, subchannelArgs) => {
|
||||||
if (!this.xdsClient || !this.latestConfig) {
|
if (!this.xdsClient || !this.latestConfig || !this.lastestEndpointList) {
|
||||||
throw new Error('xds_cluster_impl: invalid state: createSubchannel called with xdsClient or latestConfig not populated');
|
throw new Error('xds_cluster_impl: invalid state: createSubchannel called with xdsClient or latestConfig not populated');
|
||||||
}
|
}
|
||||||
const locality = (subchannelAddress as LocalitySubchannelAddress).locality ?? '';
|
|
||||||
const wrapperChild = channelControlHelper.createSubchannel(subchannelAddress, subchannelArgs);
|
const wrapperChild = channelControlHelper.createSubchannel(subchannelAddress, subchannelArgs);
|
||||||
|
let locality: Locality__Output | null = null;
|
||||||
|
for (const endpoint of this.lastestEndpointList) {
|
||||||
|
if (endpointHasAddress(endpoint, subchannelAddress)) {
|
||||||
|
locality = (endpoint as LocalityEndpoint).locality;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (locality === null) {
|
||||||
|
trace('Not reporting load for address ' + subchannelAddressToString(subchannelAddress) + ' because it has unknown locality.');
|
||||||
|
return wrapperChild;
|
||||||
|
}
|
||||||
const lrsServer = this.latestConfig.getLrsLoadReportingServer();
|
const lrsServer = this.latestConfig.getLrsLoadReportingServer();
|
||||||
let statsObj: XdsClusterLocalityStats | null = null;
|
let statsObj: XdsClusterLocalityStats | null = null;
|
||||||
if (lrsServer) {
|
if (lrsServer) {
|
||||||
|
@ -279,15 +292,15 @@ class XdsClusterImplBalancer implements LoadBalancer {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
updateAddressList(addressList: SubchannelAddress[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
||||||
if (!(lbConfig instanceof XdsClusterImplLoadBalancingConfig)) {
|
if (!(lbConfig instanceof XdsClusterImplLoadBalancingConfig)) {
|
||||||
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig.toJsonObject(), undefined, 2));
|
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig.toJsonObject(), undefined, 2));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
trace('Received update with config: ' + JSON.stringify(lbConfig, undefined, 2));
|
trace('Received update with config: ' + JSON.stringify(lbConfig, undefined, 2));
|
||||||
|
this.lastestEndpointList = endpointList;
|
||||||
this.latestConfig = lbConfig;
|
this.latestConfig = lbConfig;
|
||||||
this.xdsClient = attributes.xdsClient as XdsClient;
|
this.xdsClient = attributes.xdsClient as XdsClient;
|
||||||
|
|
||||||
if (lbConfig.getLrsLoadReportingServer()) {
|
if (lbConfig.getLrsLoadReportingServer()) {
|
||||||
this.clusterDropStats = this.xdsClient.addClusterDropStats(
|
this.clusterDropStats = this.xdsClient.addClusterDropStats(
|
||||||
lbConfig.getLrsLoadReportingServer()!,
|
lbConfig.getLrsLoadReportingServer()!,
|
||||||
|
@ -296,7 +309,7 @@ class XdsClusterImplBalancer implements LoadBalancer {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.childBalancer.updateAddressList(addressList, lbConfig.getChildPolicy(), attributes);
|
this.childBalancer.updateAddressList(endpointList, lbConfig.getChildPolicy(), attributes);
|
||||||
}
|
}
|
||||||
exitIdle(): void {
|
exitIdle(): void {
|
||||||
this.childBalancer.exitIdle();
|
this.childBalancer.exitIdle();
|
||||||
|
|
|
@ -25,7 +25,7 @@ import PickArgs = experimental.PickArgs;
|
||||||
import PickResultType = experimental.PickResultType;
|
import PickResultType = experimental.PickResultType;
|
||||||
import UnavailablePicker = experimental.UnavailablePicker;
|
import UnavailablePicker = experimental.UnavailablePicker;
|
||||||
import QueuePicker = experimental.QueuePicker;
|
import QueuePicker = experimental.QueuePicker;
|
||||||
import SubchannelAddress = experimental.SubchannelAddress;
|
import Endpoint = experimental.Endpoint;
|
||||||
import ChildLoadBalancerHandler = experimental.ChildLoadBalancerHandler;
|
import ChildLoadBalancerHandler = experimental.ChildLoadBalancerHandler;
|
||||||
import ChannelControlHelper = experimental.ChannelControlHelper;
|
import ChannelControlHelper = experimental.ChannelControlHelper;
|
||||||
import selectLbConfigFromList = experimental.selectLbConfigFromList;
|
import selectLbConfigFromList = experimental.selectLbConfigFromList;
|
||||||
|
@ -111,7 +111,7 @@ class XdsClusterManagerPicker implements Picker {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface XdsClusterManagerChild {
|
interface XdsClusterManagerChild {
|
||||||
updateAddressList(addressList: SubchannelAddress[], childConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void;
|
updateAddressList(endpointList: Endpoint[], childConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void;
|
||||||
exitIdle(): void;
|
exitIdle(): void;
|
||||||
resetBackoff(): void;
|
resetBackoff(): void;
|
||||||
destroy(): void;
|
destroy(): void;
|
||||||
|
@ -142,8 +142,8 @@ class XdsClusterManager implements LoadBalancer {
|
||||||
this.picker = picker;
|
this.picker = picker;
|
||||||
this.parent.maybeUpdateState();
|
this.parent.maybeUpdateState();
|
||||||
}
|
}
|
||||||
updateAddressList(addressList: SubchannelAddress[], childConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
updateAddressList(endpointList: Endpoint[], childConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
||||||
this.childBalancer.updateAddressList(addressList, childConfig, attributes);
|
this.childBalancer.updateAddressList(endpointList, childConfig, attributes);
|
||||||
}
|
}
|
||||||
exitIdle(): void {
|
exitIdle(): void {
|
||||||
this.childBalancer.exitIdle();
|
this.childBalancer.exitIdle();
|
||||||
|
@ -235,7 +235,7 @@ class XdsClusterManager implements LoadBalancer {
|
||||||
this.channelControlHelper.updateState(connectivityState, picker);
|
this.channelControlHelper.updateState(connectivityState, picker);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAddressList(addressList: SubchannelAddress[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
||||||
if (!(lbConfig instanceof XdsClusterManagerLoadBalancingConfig)) {
|
if (!(lbConfig instanceof XdsClusterManagerLoadBalancingConfig)) {
|
||||||
// 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.toJsonObject(), undefined, 2));
|
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig.toJsonObject(), undefined, 2));
|
||||||
|
@ -259,7 +259,7 @@ class XdsClusterManager implements LoadBalancer {
|
||||||
for (const [name, childConfig] of configChildren.entries()) {
|
for (const [name, childConfig] of configChildren.entries()) {
|
||||||
if (!this.children.has(name)) {
|
if (!this.children.has(name)) {
|
||||||
const newChild = new this.XdsClusterManagerChildImpl(this, name);
|
const newChild = new this.XdsClusterManagerChildImpl(this, name);
|
||||||
newChild.updateAddressList(addressList, childConfig, attributes);
|
newChild.updateAddressList(endpointList, childConfig, attributes);
|
||||||
this.children.set(name, newChild);
|
this.children.set(name, newChild);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { registerLoadBalancerType } from "@grpc/grpc-js/build/src/load-balancer"
|
||||||
import { EXPERIMENTAL_OUTLIER_DETECTION } from "./environment";
|
import { EXPERIMENTAL_OUTLIER_DETECTION } from "./environment";
|
||||||
import { Locality__Output } from "./generated/envoy/config/core/v3/Locality";
|
import { Locality__Output } from "./generated/envoy/config/core/v3/Locality";
|
||||||
import { ClusterLoadAssignment__Output } from "./generated/envoy/config/endpoint/v3/ClusterLoadAssignment";
|
import { ClusterLoadAssignment__Output } from "./generated/envoy/config/endpoint/v3/ClusterLoadAssignment";
|
||||||
import { LocalitySubchannelAddress, PriorityChildRaw } from "./load-balancer-priority";
|
import { LocalityEndpoint, PriorityChildRaw } from "./load-balancer-priority";
|
||||||
import { getSingletonXdsClient, Watcher, XdsClient } from "./xds-client";
|
import { getSingletonXdsClient, Watcher, XdsClient } from "./xds-client";
|
||||||
import { DropCategory } from "./load-balancer-xds-cluster-impl";
|
import { DropCategory } from "./load-balancer-xds-cluster-impl";
|
||||||
|
|
||||||
|
@ -28,11 +28,13 @@ import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
|
||||||
import LoadBalancer = experimental.LoadBalancer;
|
import LoadBalancer = experimental.LoadBalancer;
|
||||||
import Resolver = experimental.Resolver;
|
import Resolver = experimental.Resolver;
|
||||||
import SubchannelAddress = experimental.SubchannelAddress;
|
import SubchannelAddress = experimental.SubchannelAddress;
|
||||||
|
import Endpoint = experimental.Endpoint;
|
||||||
import ChildLoadBalancerHandler = experimental.ChildLoadBalancerHandler;
|
import ChildLoadBalancerHandler = experimental.ChildLoadBalancerHandler;
|
||||||
import createResolver = experimental.createResolver;
|
import createResolver = experimental.createResolver;
|
||||||
import ChannelControlHelper = experimental.ChannelControlHelper;
|
import ChannelControlHelper = experimental.ChannelControlHelper;
|
||||||
import OutlierDetectionRawConfig = experimental.OutlierDetectionRawConfig;
|
import OutlierDetectionRawConfig = experimental.OutlierDetectionRawConfig;
|
||||||
import subchannelAddressToString = experimental.subchannelAddressToString;
|
import subchannelAddressToString = experimental.subchannelAddressToString;
|
||||||
|
import endpointToString = experimental.endpointToString;
|
||||||
import selectLbConfigFromList = experimental.selectLbConfigFromList;
|
import selectLbConfigFromList = experimental.selectLbConfigFromList;
|
||||||
import parseLoadBalancingConfig = experimental.parseLoadBalancingConfig;
|
import parseLoadBalancingConfig = experimental.parseLoadBalancingConfig;
|
||||||
import UnavailablePicker = experimental.UnavailablePicker;
|
import UnavailablePicker = experimental.UnavailablePicker;
|
||||||
|
@ -116,7 +118,7 @@ class XdsClusterResolverLoadBalancingConfig implements TypedLoadBalancingConfig
|
||||||
interface LocalityEntry {
|
interface LocalityEntry {
|
||||||
locality: Locality__Output;
|
locality: Locality__Output;
|
||||||
weight: number;
|
weight: number;
|
||||||
addresses: SubchannelAddress[];
|
endpoints: Endpoint[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PriorityEntry {
|
interface PriorityEntry {
|
||||||
|
@ -164,18 +166,20 @@ function getEdsPriorities(edsUpdate: ClusterLoadAssignment__Output): PriorityEnt
|
||||||
if (!endpoint.load_balancing_weight) {
|
if (!endpoint.load_balancing_weight) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const addresses: SubchannelAddress[] = endpoint.lb_endpoints.filter(lbEndpoint => lbEndpoint.health_status === 'UNKNOWN' || lbEndpoint.health_status === 'HEALTHY').map(
|
const endpoints: Endpoint[] = endpoint.lb_endpoints.filter(lbEndpoint => lbEndpoint.health_status === 'UNKNOWN' || lbEndpoint.health_status === 'HEALTHY').map(
|
||||||
(lbEndpoint) => {
|
(lbEndpoint) => {
|
||||||
/* The validator in the XdsClient class ensures that each endpoint has
|
/* The validator in the XdsClient class ensures that each endpoint has
|
||||||
* a socket_address with an IP address and a port_value. */
|
* a socket_address with an IP address and a port_value. */
|
||||||
const socketAddress = lbEndpoint.endpoint!.address!.socket_address!;
|
const socketAddress = lbEndpoint.endpoint!.address!.socket_address!;
|
||||||
return {
|
return {
|
||||||
|
addresses: [{
|
||||||
host: socketAddress.address!,
|
host: socketAddress.address!,
|
||||||
port: socketAddress.port_value!,
|
port: socketAddress.port_value!,
|
||||||
|
}]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (addresses.length === 0) {
|
if (endpoints.length === 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let priorityEntry: PriorityEntry;
|
let priorityEntry: PriorityEntry;
|
||||||
|
@ -190,7 +194,7 @@ function getEdsPriorities(edsUpdate: ClusterLoadAssignment__Output): PriorityEnt
|
||||||
}
|
}
|
||||||
priorityEntry.localities.push({
|
priorityEntry.localities.push({
|
||||||
locality: endpoint.locality!,
|
locality: endpoint.locality!,
|
||||||
addresses: addresses,
|
endpoints: endpoints,
|
||||||
weight: endpoint.load_balancing_weight.value
|
weight: endpoint.load_balancing_weight.value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -198,7 +202,7 @@ function getEdsPriorities(edsUpdate: ClusterLoadAssignment__Output): PriorityEnt
|
||||||
return result.filter(priority => priority);
|
return result.filter(priority => priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDnsPriorities(addresses: SubchannelAddress[]): PriorityEntry[] {
|
function getDnsPriorities(endpoints: Endpoint[]): PriorityEntry[] {
|
||||||
return [{
|
return [{
|
||||||
localities: [{
|
localities: [{
|
||||||
locality: {
|
locality: {
|
||||||
|
@ -207,7 +211,7 @@ function getDnsPriorities(addresses: SubchannelAddress[]): PriorityEntry[] {
|
||||||
sub_zone: ''
|
sub_zone: ''
|
||||||
},
|
},
|
||||||
weight: 1,
|
weight: 1,
|
||||||
addresses: addresses
|
endpoints: endpoints
|
||||||
}],
|
}],
|
||||||
dropCategories: []
|
dropCategories: []
|
||||||
}];
|
}];
|
||||||
|
@ -249,7 +253,7 @@ export class XdsClusterResolver implements LoadBalancer {
|
||||||
}
|
}
|
||||||
const fullPriorityList: string[] = [];
|
const fullPriorityList: string[] = [];
|
||||||
const priorityChildren: {[name: string]: PriorityChildRaw} = {};
|
const priorityChildren: {[name: string]: PriorityChildRaw} = {};
|
||||||
const addressList: LocalitySubchannelAddress[] = [];
|
const endpointList: LocalityEndpoint[] = [];
|
||||||
const edsChildPolicy = this.latestConfig.getXdsLbPolicy();
|
const edsChildPolicy = this.latestConfig.getXdsLbPolicy();
|
||||||
for (const entry of this.discoveryMechanismList) {
|
for (const entry of this.discoveryMechanismList) {
|
||||||
const newPriorityNames: string[] = [];
|
const newPriorityNames: string[] = [];
|
||||||
|
@ -291,15 +295,15 @@ export class XdsClusterResolver implements LoadBalancer {
|
||||||
newPriorityNames[priority] = newPriorityName;
|
newPriorityNames[priority] = newPriorityName;
|
||||||
|
|
||||||
for (const localityObj of priorityEntry.localities) {
|
for (const localityObj of priorityEntry.localities) {
|
||||||
for (const address of localityObj.addresses) {
|
for (const endpoint of localityObj.endpoints) {
|
||||||
addressList.push({
|
endpointList.push({
|
||||||
localityPath: [
|
localityPath: [
|
||||||
newPriorityName,
|
newPriorityName,
|
||||||
localityToName(localityObj.locality),
|
localityToName(localityObj.locality),
|
||||||
],
|
],
|
||||||
locality: localityObj.locality,
|
locality: localityObj.locality,
|
||||||
weight: localityObj.weight,
|
weight: localityObj.weight,
|
||||||
...address,
|
...endpoint
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
newLocalityPriorities.set(localityToName(localityObj.locality), priority);
|
newLocalityPriorities.set(localityToName(localityObj.locality), priority);
|
||||||
|
@ -349,16 +353,16 @@ export class XdsClusterResolver implements LoadBalancer {
|
||||||
this.channelControlHelper.updateState(connectivityState.TRANSIENT_FAILURE, new UnavailablePicker({code: status.UNAVAILABLE, details: `LB policy config parsing failed with error ${(e as Error).message}`, metadata: new Metadata()}));
|
this.channelControlHelper.updateState(connectivityState.TRANSIENT_FAILURE, new UnavailablePicker({code: status.UNAVAILABLE, details: `LB policy config parsing failed with error ${(e as Error).message}`, metadata: new Metadata()}));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
trace('Child update addresses: ' + addressList.map(address => '(' + subchannelAddressToString(address) + ' path=' + address.localityPath + ')'));
|
trace('Child update addresses: ' + endpointList.map(endpoint => '(' + endpointToString(endpoint) + ' path=' + endpoint.localityPath + ')'));
|
||||||
trace('Child update priority config: ' + JSON.stringify(childConfig, undefined, 2));
|
trace('Child update priority config: ' + JSON.stringify(childConfig, undefined, 2));
|
||||||
this.childBalancer.updateAddressList(
|
this.childBalancer.updateAddressList(
|
||||||
addressList,
|
endpointList,
|
||||||
typedChildConfig,
|
typedChildConfig,
|
||||||
this.latestAttributes
|
this.latestAttributes
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAddressList(addressList: SubchannelAddress[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
updateAddressList(addressList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
||||||
if (!(lbConfig instanceof XdsClusterResolverLoadBalancingConfig)) {
|
if (!(lbConfig instanceof XdsClusterResolverLoadBalancingConfig)) {
|
||||||
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig, undefined, 2));
|
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig, undefined, 2));
|
||||||
return;
|
return;
|
||||||
|
@ -399,8 +403,8 @@ export class XdsClusterResolver implements LoadBalancer {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const resolver = createResolver({scheme: 'dns', path: mechanism.dns_hostname!}, {
|
const resolver = createResolver({scheme: 'dns', path: mechanism.dns_hostname!}, {
|
||||||
onSuccessfulResolution: addressList => {
|
onSuccessfulResolution: endpointList => {
|
||||||
mechanismEntry.latestUpdate = getDnsPriorities(addressList);
|
mechanismEntry.latestUpdate = getDnsPriorities(endpointList);
|
||||||
this.maybeUpdateChild();
|
this.maybeUpdateChild();
|
||||||
},
|
},
|
||||||
onError: error => {
|
onError: error => {
|
||||||
|
|
|
@ -20,13 +20,13 @@
|
||||||
import { LoadBalancingConfig, experimental, logVerbosity } from "@grpc/grpc-js";
|
import { LoadBalancingConfig, experimental, logVerbosity } from "@grpc/grpc-js";
|
||||||
import { loadProtosWithOptionsSync } from "@grpc/proto-loader/build/src/util";
|
import { loadProtosWithOptionsSync } from "@grpc/proto-loader/build/src/util";
|
||||||
import { WeightedTargetRaw } from "./load-balancer-weighted-target";
|
import { WeightedTargetRaw } from "./load-balancer-weighted-target";
|
||||||
import { isLocalitySubchannelAddress } from "./load-balancer-priority";
|
import { isLocalityEndpoint } from "./load-balancer-priority";
|
||||||
import { localityToName } from "./load-balancer-xds-cluster-resolver";
|
import { localityToName } from "./load-balancer-xds-cluster-resolver";
|
||||||
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
|
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
|
||||||
import LoadBalancer = experimental.LoadBalancer;
|
import LoadBalancer = experimental.LoadBalancer;
|
||||||
import ChannelControlHelper = experimental.ChannelControlHelper;
|
import ChannelControlHelper = experimental.ChannelControlHelper;
|
||||||
import ChildLoadBalancerHandler = experimental.ChildLoadBalancerHandler;
|
import ChildLoadBalancerHandler = experimental.ChildLoadBalancerHandler;
|
||||||
import SubchannelAddress = experimental.SubchannelAddress;
|
import Endpoint = experimental.Endpoint;
|
||||||
import parseLoadBalancingConfig = experimental.parseLoadBalancingConfig;
|
import parseLoadBalancingConfig = experimental.parseLoadBalancingConfig;
|
||||||
import registerLoadBalancerType = experimental.registerLoadBalancerType;
|
import registerLoadBalancerType = experimental.registerLoadBalancerType;
|
||||||
import { Any__Output } from "./generated/google/protobuf/Any";
|
import { Any__Output } from "./generated/google/protobuf/Any";
|
||||||
|
@ -76,14 +76,14 @@ class XdsWrrLocalityLoadBalancer implements LoadBalancer {
|
||||||
constructor(private readonly channelControlHelper: ChannelControlHelper) {
|
constructor(private readonly channelControlHelper: ChannelControlHelper) {
|
||||||
this.childBalancer = new ChildLoadBalancerHandler(channelControlHelper);
|
this.childBalancer = new ChildLoadBalancerHandler(channelControlHelper);
|
||||||
}
|
}
|
||||||
updateAddressList(addressList: SubchannelAddress[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
||||||
if (!(lbConfig instanceof XdsWrrLocalityLoadBalancingConfig)) {
|
if (!(lbConfig instanceof XdsWrrLocalityLoadBalancingConfig)) {
|
||||||
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig, undefined, 2));
|
trace('Discarding address list update with unrecognized config ' + JSON.stringify(lbConfig, undefined, 2));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const targets: {[localityName: string]: WeightedTargetRaw} = {};
|
const targets: {[localityName: string]: WeightedTargetRaw} = {};
|
||||||
for (const address of addressList) {
|
for (const address of endpointList) {
|
||||||
if (!isLocalitySubchannelAddress(address)) {
|
if (!isLocalityEndpoint(address)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const localityName = localityToName(address.locality);
|
const localityName = localityToName(address.locality);
|
||||||
|
@ -99,7 +99,7 @@ class XdsWrrLocalityLoadBalancer implements LoadBalancer {
|
||||||
targets: targets
|
targets: targets
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.childBalancer.updateAddressList(addressList, parseLoadBalancingConfig(childConfig), attributes);
|
this.childBalancer.updateAddressList(endpointList, parseLoadBalancingConfig(childConfig), attributes);
|
||||||
}
|
}
|
||||||
exitIdle(): void {
|
exitIdle(): void {
|
||||||
this.childBalancer.exitIdle();
|
this.childBalancer.exitIdle();
|
||||||
|
|
|
@ -30,7 +30,7 @@ import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
|
||||||
import LoadBalancer = experimental.LoadBalancer;
|
import LoadBalancer = experimental.LoadBalancer;
|
||||||
import ChannelControlHelper = experimental.ChannelControlHelper;
|
import ChannelControlHelper = experimental.ChannelControlHelper;
|
||||||
import ChildLoadBalancerHandler = experimental.ChildLoadBalancerHandler;
|
import ChildLoadBalancerHandler = experimental.ChildLoadBalancerHandler;
|
||||||
import SubchannelAddress = experimental.SubchannelAddress;
|
import Endpoint = experimental.Endpoint;
|
||||||
import Picker = experimental.Picker;
|
import Picker = experimental.Picker;
|
||||||
import PickArgs = experimental.PickArgs;
|
import PickArgs = experimental.PickArgs;
|
||||||
import PickResult = experimental.PickResult;
|
import PickResult = experimental.PickResult;
|
||||||
|
@ -94,12 +94,12 @@ class RpcBehaviorLoadBalancer implements LoadBalancer {
|
||||||
});
|
});
|
||||||
this.child = new ChildLoadBalancerHandler(childChannelControlHelper);
|
this.child = new ChildLoadBalancerHandler(childChannelControlHelper);
|
||||||
}
|
}
|
||||||
updateAddressList(addressList: SubchannelAddress[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
|
||||||
if (!(lbConfig instanceof RpcBehaviorLoadBalancingConfig)) {
|
if (!(lbConfig instanceof RpcBehaviorLoadBalancingConfig)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.latestConfig = lbConfig;
|
this.latestConfig = lbConfig;
|
||||||
this.child.updateAddressList(addressList, RPC_BEHAVIOR_CHILD_CONFIG, attributes);
|
this.child.updateAddressList(endpointList, RPC_BEHAVIOR_CHILD_CONFIG, attributes);
|
||||||
}
|
}
|
||||||
exitIdle(): void {
|
exitIdle(): void {
|
||||||
this.child.exitIdle();
|
this.child.exitIdle();
|
||||||
|
|
Loading…
Reference in New Issue