grpc-js: Enable LB policies to override subchannel credentials

This commit is contained in:
Michael Lumish 2024-09-06 11:09:24 -07:00
parent 21f470824c
commit 57f0a71399
18 changed files with 88 additions and 60 deletions

View File

@ -88,7 +88,7 @@ const RPC_BEHAVIOR_CHILD_CONFIG = parseLoadBalancingConfig({round_robin: {}});
class RpcBehaviorLoadBalancer implements LoadBalancer {
private child: ChildLoadBalancerHandler;
private latestConfig: RpcBehaviorLoadBalancingConfig | null = null;
constructor(channelControlHelper: ChannelControlHelper, options: grpc.ChannelOptions) {
constructor(channelControlHelper: ChannelControlHelper, credentials: grpc.ChannelCredentials, options: grpc.ChannelOptions) {
const childChannelControlHelper = createChildChannelControlHelper(channelControlHelper, {
updateState: (connectivityState, picker) => {
if (connectivityState === grpc.connectivityState.READY && this.latestConfig) {
@ -97,7 +97,7 @@ class RpcBehaviorLoadBalancer implements LoadBalancer {
channelControlHelper.updateState(connectivityState, picker);
}
});
this.child = new ChildLoadBalancerHandler(childChannelControlHelper, options);
this.child = new ChildLoadBalancerHandler(childChannelControlHelper, credentials, options);
}
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
if (!(lbConfig instanceof RpcBehaviorLoadBalancingConfig)) {

View File

@ -15,7 +15,7 @@
*
*/
import { connectivityState, status, Metadata, logVerbosity, experimental, LoadBalancingConfig, ChannelOptions } from '@grpc/grpc-js';
import { connectivityState, status, Metadata, logVerbosity, experimental, LoadBalancingConfig, ChannelOptions, ChannelCredentials } from '@grpc/grpc-js';
import { getSingletonXdsClient, Watcher, XdsClient } from './xds-client';
import { Cluster__Output } from './generated/envoy/config/cluster/v3/Cluster';
import Endpoint = experimental.Endpoint;
@ -155,8 +155,8 @@ export class CdsLoadBalancer implements LoadBalancer {
private updatedChild = false;
constructor(private readonly channelControlHelper: ChannelControlHelper, options: ChannelOptions) {
this.childBalancer = new XdsClusterResolverChildPolicyHandler(channelControlHelper, options);
constructor(private readonly channelControlHelper: ChannelControlHelper, credentials: ChannelCredentials, options: ChannelOptions) {
this.childBalancer = new XdsClusterResolverChildPolicyHandler(channelControlHelper, credentials, options);
}
private reportError(errorMessage: string) {

View File

@ -15,7 +15,7 @@
*
*/
import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity as LogVerbosity, experimental, LoadBalancingConfig, ChannelOptions } from '@grpc/grpc-js';
import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity as LogVerbosity, experimental, LoadBalancingConfig, ChannelOptions, ChannelCredentials } from '@grpc/grpc-js';
import LoadBalancer = experimental.LoadBalancer;
import ChannelControlHelper = experimental.ChannelControlHelper;
import registerLoadBalancerType = experimental.registerLoadBalancerType;
@ -197,7 +197,7 @@ export class PriorityLoadBalancer implements LoadBalancer {
this.parent.channelControlHelper.requestReresolution();
}
}
}), parent.options);
}), parent.credentials, parent.options);
this.picker = new QueuePicker(this.childBalancer);
this.startFailoverTimer();
}
@ -323,7 +323,7 @@ export class PriorityLoadBalancer implements LoadBalancer {
private updatesPaused = false;
constructor(private channelControlHelper: ChannelControlHelper, private options: ChannelOptions) {}
constructor(private channelControlHelper: ChannelControlHelper, private credentials: ChannelCredentials, private options: ChannelOptions) {}
private updateState(state: ConnectivityState, picker: Picker) {
trace(

View File

@ -15,7 +15,7 @@
*
*/
import { experimental, logVerbosity, connectivityState, status, Metadata, ChannelOptions, LoadBalancingConfig } from '@grpc/grpc-js';
import { experimental, logVerbosity, connectivityState, status, Metadata, ChannelOptions, LoadBalancingConfig, ChannelCredentials } from '@grpc/grpc-js';
import { isLocalityEndpoint } from './load-balancer-priority';
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
import LeafLoadBalancer = experimental.LeafLoadBalancer;
@ -226,7 +226,7 @@ class RingHashLoadBalancer implements LoadBalancer {
private currentState: connectivityState = connectivityState.IDLE;
private ring: RingEntry[] = [];
private ringHashSizeCap = DEFAULT_RING_SIZE_CAP;
constructor(private channelControlHelper: ChannelControlHelper, private options: ChannelOptions) {
constructor(private channelControlHelper: ChannelControlHelper, private credentials: ChannelCredentials, private options: ChannelOptions) {
this.childChannelControlHelper = createChildChannelControlHelper(
channelControlHelper,
{
@ -407,7 +407,7 @@ class RingHashLoadBalancer implements LoadBalancer {
} else {
this.leafMap.set(
endpoint,
new LeafLoadBalancer(endpoint, this.childChannelControlHelper, this.options)
new LeafLoadBalancer(endpoint, this.childChannelControlHelper, this.credentials, this.options)
);
}
const weight = this.leafWeightMap.get(endpoint);

View File

@ -15,7 +15,7 @@
*
*/
import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity, experimental, LoadBalancingConfig, ChannelOptions } from "@grpc/grpc-js";
import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity, experimental, LoadBalancingConfig, ChannelOptions, ChannelCredentials } from "@grpc/grpc-js";
import { isLocalityEndpoint, LocalityEndpoint } from "./load-balancer-priority";
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
import LoadBalancer = experimental.LoadBalancer;
@ -178,7 +178,7 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
updateState: (connectivityState: ConnectivityState, picker: Picker) => {
this.updateState(connectivityState, picker);
},
}), parent.options);
}), parent.credentials, parent.options);
this.picker = new QueuePicker(this.childBalancer);
}
@ -243,7 +243,7 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
private targetList: string[] = [];
private updatesPaused = false;
constructor(private channelControlHelper: ChannelControlHelper, private options: ChannelOptions) {}
constructor(private channelControlHelper: ChannelControlHelper, private credentials: ChannelCredentials, private options: ChannelOptions) {}
private maybeUpdateState() {
if (!this.updatesPaused) {

View File

@ -15,7 +15,7 @@
*
*/
import { experimental, logVerbosity, status as Status, Metadata, connectivityState, ChannelOptions } from "@grpc/grpc-js";
import { experimental, logVerbosity, status as Status, Metadata, connectivityState, ChannelOptions, ChannelCredentials } from "@grpc/grpc-js";
import { validateXdsServerConfig, XdsServerConfig } from "./xds-bootstrap";
import { getSingletonXdsClient, XdsClient, XdsClusterDropStats, XdsClusterLocalityStats } from "./xds-client";
import { LocalityEndpoint } from "./load-balancer-priority";
@ -253,13 +253,13 @@ class XdsClusterImplBalancer implements LoadBalancer {
private clusterDropStats: XdsClusterDropStats | null = null;
private xdsClient: XdsClient | null = null;
constructor(private readonly channelControlHelper: ChannelControlHelper, options: ChannelOptions) {
constructor(private readonly channelControlHelper: ChannelControlHelper, credentials: ChannelCredentials, options: ChannelOptions) {
this.childBalancer = new ChildLoadBalancerHandler(createChildChannelControlHelper(channelControlHelper, {
createSubchannel: (subchannelAddress, subchannelArgs) => {
createSubchannel: (subchannelAddress, subchannelArgs, credentialsOverride) => {
if (!this.xdsClient || !this.latestConfig || !this.lastestEndpointList) {
throw new Error('xds_cluster_impl: invalid state: createSubchannel called with xdsClient or latestConfig not populated');
}
const wrapperChild = channelControlHelper.createSubchannel(subchannelAddress, subchannelArgs);
const wrapperChild = channelControlHelper.createSubchannel(subchannelAddress, subchannelArgs, credentialsOverride);
let locality: Locality__Output | null = null;
for (const endpoint of this.lastestEndpointList) {
if (endpointHasAddress(endpoint, subchannelAddress)) {
@ -290,7 +290,7 @@ class XdsClusterImplBalancer implements LoadBalancer {
channelControlHelper.updateState(connectivityState, picker);
}
}
}), options);
}), credentials, options);
}
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
if (!(lbConfig instanceof XdsClusterImplLoadBalancingConfig)) {

View File

@ -15,7 +15,7 @@
*
*/
import { connectivityState as ConnectivityState, status as Status, experimental, logVerbosity, Metadata, status, ChannelOptions } from "@grpc/grpc-js/";
import { connectivityState as ConnectivityState, status as Status, experimental, logVerbosity, Metadata, status, ChannelOptions, ChannelCredentials } from "@grpc/grpc-js/";
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
import LoadBalancer = experimental.LoadBalancer;
@ -131,7 +131,7 @@ class XdsClusterManager implements LoadBalancer {
updateState: (connectivityState: ConnectivityState, picker: Picker) => {
this.updateState(connectivityState, picker);
},
}), parent.options);
}), parent.credentials, parent.options);
this.picker = new QueuePicker(this.childBalancer);
}
@ -167,7 +167,7 @@ class XdsClusterManager implements LoadBalancer {
// Shutdown is a placeholder value that will never appear in normal operation.
private currentState: ConnectivityState = ConnectivityState.SHUTDOWN;
private updatesPaused = false;
constructor(private channelControlHelper: ChannelControlHelper, private options: ChannelOptions) {}
constructor(private channelControlHelper: ChannelControlHelper, private credentials: ChannelCredentials, private options: ChannelOptions) {}
private maybeUpdateState() {
if (!this.updatesPaused) {

View File

@ -15,7 +15,7 @@
*
*/
import { ChannelOptions, LoadBalancingConfig, Metadata, connectivityState, experimental, logVerbosity, status } from "@grpc/grpc-js";
import { ChannelCredentials, ChannelOptions, LoadBalancingConfig, Metadata, connectivityState, experimental, logVerbosity, status } from "@grpc/grpc-js";
import { registerLoadBalancerType } from "@grpc/grpc-js/build/src/load-balancer";
import { EXPERIMENTAL_DUALSTACK_ENDPOINTS, EXPERIMENTAL_OUTLIER_DETECTION } from "./environment";
import { Locality__Output } from "./generated/envoy/config/core/v3/Locality";
@ -249,14 +249,14 @@ export class XdsClusterResolver implements LoadBalancer {
private xdsClient: XdsClient | null = null;
private childBalancer: ChildLoadBalancerHandler;
constructor(private readonly channelControlHelper: ChannelControlHelper, options: ChannelOptions) {
constructor(private readonly channelControlHelper: ChannelControlHelper, credentials: ChannelCredentials, options: ChannelOptions) {
this.childBalancer = new ChildLoadBalancerHandler(experimental.createChildChannelControlHelper(channelControlHelper, {
requestReresolution: () => {
for (const entry of this.discoveryMechanismList) {
entry.resolver?.updateResolution();
}
}
}), options);
}), credentials, options);
}
private maybeUpdateChild() {

View File

@ -17,7 +17,7 @@
// https://github.com/grpc/proposal/blob/master/A52-xds-custom-lb-policies.md
import { ChannelOptions, LoadBalancingConfig, experimental, logVerbosity } from "@grpc/grpc-js";
import { ChannelCredentials, ChannelOptions, LoadBalancingConfig, experimental, logVerbosity } from "@grpc/grpc-js";
import { loadProtosWithOptionsSync } from "@grpc/proto-loader/build/src/util";
import { WeightedTargetRaw } from "./load-balancer-weighted-target";
import { isLocalityEndpoint } from "./load-balancer-priority";
@ -73,8 +73,8 @@ class XdsWrrLocalityLoadBalancingConfig implements TypedLoadBalancingConfig {
class XdsWrrLocalityLoadBalancer implements LoadBalancer {
private childBalancer: ChildLoadBalancerHandler;
constructor(private readonly channelControlHelper: ChannelControlHelper, options: ChannelOptions) {
this.childBalancer = new ChildLoadBalancerHandler(channelControlHelper, options);
constructor(private readonly channelControlHelper: ChannelControlHelper, credentials: ChannelCredentials, options: ChannelOptions) {
this.childBalancer = new ChildLoadBalancerHandler(channelControlHelper, credentials, options);
}
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
if (!(lbConfig instanceof XdsWrrLocalityLoadBalancingConfig)) {

View File

@ -24,7 +24,7 @@ import { ControlPlaneServer } from "./xds-server";
import * as assert from 'assert';
import { WrrLocality } from "../src/generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/WrrLocality";
import { TypedStruct } from "../src/generated/xds/type/v3/TypedStruct";
import { ChannelOptions, connectivityState, experimental, logVerbosity } from "@grpc/grpc-js";
import { ChannelCredentials, ChannelOptions, connectivityState, experimental, logVerbosity } from "@grpc/grpc-js";
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
import LoadBalancer = experimental.LoadBalancer;
@ -84,7 +84,7 @@ const RPC_BEHAVIOR_CHILD_CONFIG = parseLoadBalancingConfig({round_robin: {}});
class RpcBehaviorLoadBalancer implements LoadBalancer {
private child: ChildLoadBalancerHandler;
private latestConfig: RpcBehaviorLoadBalancingConfig | null = null;
constructor(channelControlHelper: ChannelControlHelper, options: ChannelOptions) {
constructor(channelControlHelper: ChannelControlHelper, credentials: ChannelCredentials, options: ChannelOptions) {
const childChannelControlHelper = createChildChannelControlHelper(channelControlHelper, {
updateState: (state, picker) => {
if (state === connectivityState.READY && this.latestConfig) {
@ -93,7 +93,7 @@ class RpcBehaviorLoadBalancer implements LoadBalancer {
channelControlHelper.updateState(state, picker);
}
});
this.child = new ChildLoadBalancerHandler(childChannelControlHelper, options);
this.child = new ChildLoadBalancerHandler(childChannelControlHelper, credentials, options);
}
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
if (!(lbConfig instanceof RpcBehaviorLoadBalancingConfig)) {

View File

@ -294,13 +294,14 @@ export class InternalChannel {
const channelControlHelper: ChannelControlHelper = {
createSubchannel: (
subchannelAddress: SubchannelAddress,
subchannelArgs: ChannelOptions
subchannelArgs: ChannelOptions,
credentialsOverride: ChannelCredentials | null
) => {
const subchannel = this.subchannelPool.getOrCreateSubchannel(
this.target,
subchannelAddress,
Object.assign({}, this.options, subchannelArgs),
this.credentials
credentialsOverride ?? this.credentials
);
subchannel.throttleKeepalive(this.keepaliveTime);
if (this.channelzEnabled) {
@ -349,6 +350,7 @@ export class InternalChannel {
this.resolvingLoadBalancer = new ResolvingLoadBalancer(
this.target,
channelControlHelper,
credentials,
options,
(serviceConfig, configSelector) => {
if (serviceConfig.retryThrottling) {

View File

@ -27,6 +27,7 @@ import { ConnectivityState } from './connectivity-state';
import { Picker } from './picker';
import type { ChannelRef, SubchannelRef } from './channelz';
import { SubchannelInterface } from './subchannel-interface';
import { ChannelCredentials } from './channel-credentials';
const TYPE_NAME = 'child_load_balancer_helper';
@ -40,11 +41,13 @@ export class ChildLoadBalancerHandler implements LoadBalancer {
constructor(private parent: ChildLoadBalancerHandler) {}
createSubchannel(
subchannelAddress: SubchannelAddress,
subchannelArgs: ChannelOptions
subchannelArgs: ChannelOptions,
credentialsOverride: ChannelCredentials | null
): SubchannelInterface {
return this.parent.channelControlHelper.createSubchannel(
subchannelAddress,
subchannelArgs
subchannelArgs,
credentialsOverride
);
}
updateState(connectivityState: ConnectivityState, picker: Picker): void {
@ -86,6 +89,7 @@ export class ChildLoadBalancerHandler implements LoadBalancer {
constructor(
private readonly channelControlHelper: ChannelControlHelper,
private readonly credentials: ChannelCredentials,
private readonly options: ChannelOptions
) {}
@ -114,7 +118,7 @@ export class ChildLoadBalancerHandler implements LoadBalancer {
this.configUpdateRequiresNewPolicyInstance(this.latestConfig, lbConfig)
) {
const newHelper = new this.ChildPolicyHelper(this);
const newChild = createLoadBalancer(lbConfig, newHelper, this.options)!;
const newChild = createLoadBalancer(lbConfig, newHelper, this.credentials, this.options)!;
newHelper.setChild(newChild);
if (this.currentChild === null) {
this.currentChild = newChild;

View File

@ -43,6 +43,7 @@ import {
} from './subchannel-interface';
import * as logging from './logging';
import { LoadBalancingConfig } from './service-config';
import { ChannelCredentials } from './channel-credentials';
const TRACER_NAME = 'outlier_detection';
@ -469,17 +470,20 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer {
constructor(
channelControlHelper: ChannelControlHelper,
credentials: ChannelCredentials,
options: ChannelOptions
) {
this.childBalancer = new ChildLoadBalancerHandler(
createChildChannelControlHelper(channelControlHelper, {
createSubchannel: (
subchannelAddress: SubchannelAddress,
subchannelArgs: ChannelOptions
subchannelArgs: ChannelOptions,
credentialsOverride: ChannelCredentials | null
) => {
const originalSubchannel = channelControlHelper.createSubchannel(
subchannelAddress,
subchannelArgs
subchannelArgs,
credentialsOverride
);
const mapEntry =
this.entryMap.getForSubchannelAddress(subchannelAddress);
@ -505,6 +509,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer {
}
},
}),
credentials,
options
);
this.ejectionTimer = setInterval(() => {}, 0);

View File

@ -43,6 +43,7 @@ import {
import { isTcpSubchannelAddress } from './subchannel-address';
import { isIPv6 } from 'net';
import { ChannelOptions } from './channel-options';
import { ChannelCredentials } from './channel-credentials';
const TRACER_NAME = 'pick_first';
@ -248,6 +249,7 @@ export class PickFirstLoadBalancer implements LoadBalancer {
*/
constructor(
private readonly channelControlHelper: ChannelControlHelper,
credentials: ChannelCredentials,
options: ChannelOptions
) {
this.connectionDelayTimeout = setTimeout(() => {}, 0);
@ -480,7 +482,7 @@ export class PickFirstLoadBalancer implements LoadBalancer {
private connectToAddressList(addressList: SubchannelAddress[]) {
const newChildrenList = addressList.map(address => ({
subchannel: this.channelControlHelper.createSubchannel(address, {}),
subchannel: this.channelControlHelper.createSubchannel(address, {}, null),
hasReportedTransientFailure: false,
}));
trace('connectToAddressList([' + addressList.map(address => subchannelAddressToString(address)) + '])');
@ -579,6 +581,7 @@ export class LeafLoadBalancer {
constructor(
private endpoint: Endpoint,
channelControlHelper: ChannelControlHelper,
credentials: ChannelCredentials,
options: ChannelOptions
) {
const childChannelControlHelper = createChildChannelControlHelper(
@ -593,6 +596,7 @@ export class LeafLoadBalancer {
);
this.pickFirstBalancer = new PickFirstLoadBalancer(
childChannelControlHelper,
credentials,
{ ...options, [REPORT_HEALTH_STATUS_OPTION_NAME]: true }
);
this.latestPicker = new QueuePicker(this.pickFirstBalancer);

View File

@ -39,6 +39,7 @@ import {
} from './subchannel-address';
import { LeafLoadBalancer } from './load-balancer-pick-first';
import { ChannelOptions } from './channel-options';
import { ChannelCredentials } from './channel-credentials';
const TRACER_NAME = 'round_robin';
@ -104,6 +105,7 @@ export class RoundRobinLoadBalancer implements LoadBalancer {
constructor(
private readonly channelControlHelper: ChannelControlHelper,
private readonly credentials: ChannelCredentials,
private readonly options: ChannelOptions
) {
this.childChannelControlHelper = createChildChannelControlHelper(
@ -207,6 +209,7 @@ export class RoundRobinLoadBalancer implements LoadBalancer {
new LeafLoadBalancer(
endpoint,
this.childChannelControlHelper,
this.credentials,
this.options
)
);

View File

@ -24,6 +24,7 @@ import { SubchannelInterface } from './subchannel-interface';
import { LoadBalancingConfig } from './service-config';
import { log } from './logging';
import { LogVerbosity } from './constants';
import { ChannelCredentials } from './channel-credentials';
/**
* A collection of functions associated with a channel that a load balancer
@ -37,7 +38,8 @@ export interface ChannelControlHelper {
*/
createSubchannel(
subchannelAddress: SubchannelAddress,
subchannelArgs: ChannelOptions
subchannelArgs: ChannelOptions,
credentialsOverride: ChannelCredentials | null
): SubchannelInterface;
/**
* Passes a new subchannel picker up to the channel. This is called if either
@ -130,6 +132,7 @@ export interface LoadBalancer {
export interface LoadBalancerConstructor {
new (
channelControlHelper: ChannelControlHelper,
credentials: ChannelCredentials,
options: ChannelOptions
): LoadBalancer;
}
@ -173,12 +176,14 @@ export function registerDefaultLoadBalancerType(typeName: string) {
export function createLoadBalancer(
config: TypedLoadBalancingConfig,
channelControlHelper: ChannelControlHelper,
credentials: ChannelCredentials,
options: ChannelOptions
): LoadBalancer | null {
const typeName = config.getLoadBalancerName();
if (typeName in registeredLoadBalancerTypes) {
return new registeredLoadBalancerTypes[typeName].LoadBalancer(
channelControlHelper,
credentials,
options
);
} else {

View File

@ -40,6 +40,7 @@ import { Endpoint } from './subchannel-address';
import { GrpcUri, uriToString } from './uri-parser';
import { ChildLoadBalancerHandler } from './load-balancer-child-handler';
import { ChannelOptions } from './channel-options';
import { ChannelCredentials } from './channel-credentials';
const TRACER_NAME = 'resolving_load_balancer';
@ -198,6 +199,7 @@ export class ResolvingLoadBalancer implements LoadBalancer {
constructor(
private readonly target: GrpcUri,
private readonly channelControlHelper: ChannelControlHelper,
credentials: ChannelCredentials,
channelOptions: ChannelOptions,
private readonly onSuccessfulResolution: ResolutionCallback,
private readonly onFailedResolution: ResolutionFailureCallback
@ -243,6 +245,7 @@ export class ResolvingLoadBalancer implements LoadBalancer {
removeChannelzChild:
channelControlHelper.removeChannelzChild.bind(channelControlHelper),
},
credentials,
channelOptions
);
this.innerResolver = createResolver(

View File

@ -31,6 +31,7 @@ import { Metadata } from '../src/metadata';
import { Picker } from '../src/picker';
import { Endpoint, subchannelAddressToString } from '../src/subchannel-address';
import { MockSubchannel, TestClient, TestServer } from './common';
import { credentials } from '../src';
function updateStateCallBackForExpectedStateSequence(
expectedStateSequence: ConnectivityState[],
@ -97,6 +98,7 @@ describe('Shuffler', () => {
describe('pick_first load balancing policy', () => {
const config = new PickFirstLoadBalancingConfig(false);
let subchannels: MockSubchannel[] = [];
const creds = credentials.createInsecure();
const baseChannelControlHelper: ChannelControlHelper = {
createSubchannel: (subchannelAddress, subchannelArgs) => {
const subchannel = new MockSubchannel(
@ -123,7 +125,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[{ addresses: [{ host: 'localhost', port: 1 }] }],
config
@ -142,7 +144,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[
{ addresses: [{ host: 'localhost', port: 1 }] },
@ -164,7 +166,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[
{
@ -198,7 +200,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[{ addresses: [{ host: 'localhost', port: 1 }] }],
config
@ -214,7 +216,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[
{ addresses: [{ host: 'localhost', port: 1 }] },
@ -236,7 +238,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[
{ addresses: [{ host: 'localhost', port: 1 }] },
@ -261,7 +263,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[
{ addresses: [{ host: 'localhost', port: 1 }] },
@ -300,7 +302,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[
{ addresses: [{ host: 'localhost', port: 1 }] },
@ -327,7 +329,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[
{ addresses: [{ host: 'localhost', port: 1 }] },
@ -358,7 +360,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[
{ addresses: [{ host: 'localhost', port: 1 }] },
@ -396,7 +398,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[
{ addresses: [{ host: 'localhost', port: 1 }] },
@ -431,7 +433,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[{ addresses: [{ host: 'localhost', port: 1 }] }],
config
@ -459,7 +461,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[{ addresses: [{ host: 'localhost', port: 1 }] }],
config
@ -494,7 +496,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[{ addresses: [{ host: 'localhost', port: 1 }] }],
config
@ -529,7 +531,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[{ addresses: [{ host: 'localhost', port: 1 }] }],
config
@ -575,7 +577,7 @@ describe('pick_first load balancing policy', () => {
},
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[{ addresses: [{ host: 'localhost', port: 1 }] }],
config
@ -635,7 +637,7 @@ describe('pick_first load balancing policy', () => {
},
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[{ addresses: [{ host: 'localhost', port: 1 }] }],
config
@ -676,7 +678,7 @@ describe('pick_first load balancing policy', () => {
),
}
);
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(
[{ addresses: [{ host: 'localhost', port: 1 }] }],
config
@ -720,7 +722,7 @@ describe('pick_first load balancing policy', () => {
for (let i = 0; i < 10; i++) {
endpoints.push({ addresses: [{ host: 'localhost', port: i + 1 }] });
}
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
/* Pick from 10 subchannels 5 times, with address randomization enabled,
* and verify that at least two different subchannels are picked. The
* probability choosing the same address every time is 1/10,000, which
@ -776,7 +778,7 @@ describe('pick_first load balancing policy', () => {
for (let i = 0; i < 10; i++) {
endpoints.push({ addresses: [{ host: 'localhost', port: i + 1 }] });
}
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {});
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
pickFirst.updateAddressList(endpoints, config);
process.nextTick(() => {
pickFirst.updateAddressList(endpoints, config);