Skip to content

Commit

Permalink
Merge pull request #2566 from murgatroid99/grpc-js_load_balancer_chan…
Browse files Browse the repository at this point in the history
…nel_args

grpc-js: Pass channel options to LoadBalancer constructors
  • Loading branch information
murgatroid99 committed Sep 6, 2023
2 parents 092d1e9 + 00e1ac4 commit 71d8118
Show file tree
Hide file tree
Showing 16 changed files with 110 additions and 78 deletions.
4 changes: 2 additions & 2 deletions packages/grpc-js-xds/interop/xds-interop-client.ts
Expand Up @@ -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) {
constructor(channelControlHelper: ChannelControlHelper, options: grpc.ChannelOptions) {
const childChannelControlHelper = createChildChannelControlHelper(channelControlHelper, {
updateState: (connectivityState, picker) => {
if (connectivityState === grpc.connectivityState.READY && this.latestConfig) {
Expand All @@ -97,7 +97,7 @@ class RpcBehaviorLoadBalancer implements LoadBalancer {
channelControlHelper.updateState(connectivityState, picker);
}
});
this.child = new ChildLoadBalancerHandler(childChannelControlHelper);
this.child = new ChildLoadBalancerHandler(childChannelControlHelper, options);
}
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
if (!(lbConfig instanceof RpcBehaviorLoadBalancingConfig)) {
Expand Down
6 changes: 3 additions & 3 deletions packages/grpc-js-xds/src/load-balancer-cds.ts
Expand Up @@ -15,7 +15,7 @@
*
*/

import { connectivityState, status, Metadata, logVerbosity, experimental, LoadBalancingConfig } from '@grpc/grpc-js';
import { connectivityState, status, Metadata, logVerbosity, experimental, LoadBalancingConfig, ChannelOptions } 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;
Expand Down Expand Up @@ -155,8 +155,8 @@ export class CdsLoadBalancer implements LoadBalancer {

private updatedChild = false;

constructor(private readonly channelControlHelper: ChannelControlHelper) {
this.childBalancer = new XdsClusterResolverChildPolicyHandler(channelControlHelper);
constructor(private readonly channelControlHelper: ChannelControlHelper, options: ChannelOptions) {
this.childBalancer = new XdsClusterResolverChildPolicyHandler(channelControlHelper, options);
}

private reportError(errorMessage: string) {
Expand Down
6 changes: 3 additions & 3 deletions packages/grpc-js-xds/src/load-balancer-priority.ts
Expand Up @@ -15,7 +15,7 @@
*
*/

import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity as LogVerbosity, experimental, LoadBalancingConfig } from '@grpc/grpc-js';
import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity as LogVerbosity, experimental, LoadBalancingConfig, ChannelOptions } from '@grpc/grpc-js';
import LoadBalancer = experimental.LoadBalancer;
import ChannelControlHelper = experimental.ChannelControlHelper;
import registerLoadBalancerType = experimental.registerLoadBalancerType;
Expand Down Expand Up @@ -180,7 +180,7 @@ export class PriorityLoadBalancer implements LoadBalancer {
this.parent.channelControlHelper.requestReresolution();
}
}
}));
}), parent.options);
this.picker = new QueuePicker(this.childBalancer);
this.startFailoverTimer();
}
Expand Down Expand Up @@ -306,7 +306,7 @@ export class PriorityLoadBalancer implements LoadBalancer {

private updatesPaused = false;

constructor(private channelControlHelper: ChannelControlHelper) {}
constructor(private channelControlHelper: ChannelControlHelper, private options: ChannelOptions) {}

private updateState(state: ConnectivityState, picker: Picker) {
trace(
Expand Down
6 changes: 3 additions & 3 deletions packages/grpc-js-xds/src/load-balancer-weighted-target.ts
Expand Up @@ -15,7 +15,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, ChannelOptions } from "@grpc/grpc-js";
import { isLocalityEndpoint, LocalityEndpoint } from "./load-balancer-priority";
import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
import LoadBalancer = experimental.LoadBalancer;
Expand Down Expand Up @@ -178,7 +178,7 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
updateState: (connectivityState: ConnectivityState, picker: Picker) => {
this.updateState(connectivityState, picker);
},
}));
}), parent.options);

this.picker = new QueuePicker(this.childBalancer);
}
Expand Down Expand Up @@ -243,7 +243,7 @@ export class WeightedTargetLoadBalancer implements LoadBalancer {
private targetList: string[] = [];
private updatesPaused = false;

constructor(private channelControlHelper: ChannelControlHelper) {}
constructor(private channelControlHelper: ChannelControlHelper, private options: ChannelOptions) {}

private maybeUpdateState() {
if (!this.updatesPaused) {
Expand Down
6 changes: 3 additions & 3 deletions packages/grpc-js-xds/src/load-balancer-xds-cluster-impl.ts
Expand Up @@ -15,7 +15,7 @@
*
*/

import { experimental, logVerbosity, status as Status, Metadata, connectivityState } from "@grpc/grpc-js";
import { experimental, logVerbosity, status as Status, Metadata, connectivityState, ChannelOptions } from "@grpc/grpc-js";
import { validateXdsServerConfig, XdsServerConfig } from "./xds-bootstrap";
import { getSingletonXdsClient, XdsClient, XdsClusterDropStats, XdsClusterLocalityStats } from "./xds-client";
import { LocalityEndpoint } from "./load-balancer-priority";
Expand Down Expand Up @@ -253,7 +253,7 @@ class XdsClusterImplBalancer implements LoadBalancer {
private clusterDropStats: XdsClusterDropStats | null = null;
private xdsClient: XdsClient | null = null;

constructor(private readonly channelControlHelper: ChannelControlHelper) {
constructor(private readonly channelControlHelper: ChannelControlHelper, options: ChannelOptions) {
this.childBalancer = new ChildLoadBalancerHandler(createChildChannelControlHelper(channelControlHelper, {
createSubchannel: (subchannelAddress, subchannelArgs) => {
if (!this.xdsClient || !this.latestConfig || !this.lastestEndpointList) {
Expand Down Expand Up @@ -290,7 +290,7 @@ class XdsClusterImplBalancer implements LoadBalancer {
channelControlHelper.updateState(connectivityState, picker);
}
}
}));
}), options);
}
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
if (!(lbConfig instanceof XdsClusterImplLoadBalancingConfig)) {
Expand Down
6 changes: 3 additions & 3 deletions packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts
Expand Up @@ -15,7 +15,7 @@
*
*/

import { connectivityState as ConnectivityState, status as Status, experimental, logVerbosity, Metadata, status } from "@grpc/grpc-js/";
import { connectivityState as ConnectivityState, status as Status, experimental, logVerbosity, Metadata, status, ChannelOptions } from "@grpc/grpc-js/";

import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
import LoadBalancer = experimental.LoadBalancer;
Expand Down Expand Up @@ -131,7 +131,7 @@ class XdsClusterManager implements LoadBalancer {
updateState: (connectivityState: ConnectivityState, picker: Picker) => {
this.updateState(connectivityState, picker);
},
}));
}), parent.options);

this.picker = new QueuePicker(this.childBalancer);
}
Expand Down Expand Up @@ -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) {}
constructor(private channelControlHelper: ChannelControlHelper, private options: ChannelOptions) {}

private maybeUpdateState() {
if (!this.updatesPaused) {
Expand Down
Expand Up @@ -15,7 +15,7 @@
*
*/

import { LoadBalancingConfig, Metadata, connectivityState, experimental, logVerbosity, status } from "@grpc/grpc-js";
import { ChannelOptions, LoadBalancingConfig, Metadata, connectivityState, experimental, logVerbosity, status } from "@grpc/grpc-js";
import { registerLoadBalancerType } from "@grpc/grpc-js/build/src/load-balancer";
import { EXPERIMENTAL_OUTLIER_DETECTION } from "./environment";
import { Locality__Output } from "./generated/envoy/config/core/v3/Locality";
Expand Down Expand Up @@ -232,14 +232,14 @@ export class XdsClusterResolver implements LoadBalancer {
private xdsClient: XdsClient | null = null;
private childBalancer: ChildLoadBalancerHandler;

constructor(private readonly channelControlHelper: ChannelControlHelper) {
constructor(private readonly channelControlHelper: ChannelControlHelper, options: ChannelOptions) {
this.childBalancer = new ChildLoadBalancerHandler(experimental.createChildChannelControlHelper(channelControlHelper, {
requestReresolution: () => {
for (const entry of this.discoveryMechanismList) {
entry.resolver?.updateResolution();
}
}
}));
}), options);
}

private maybeUpdateChild() {
Expand Down
6 changes: 3 additions & 3 deletions packages/grpc-js-xds/src/load-balancer-xds-wrr-locality.ts
Expand Up @@ -17,7 +17,7 @@

// https://github.com/grpc/proposal/blob/master/A52-xds-custom-lb-policies.md

import { LoadBalancingConfig, experimental, logVerbosity } from "@grpc/grpc-js";
import { 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";
Expand Down Expand Up @@ -73,8 +73,8 @@ class XdsWrrLocalityLoadBalancingConfig implements TypedLoadBalancingConfig {

class XdsWrrLocalityLoadBalancer implements LoadBalancer {
private childBalancer: ChildLoadBalancerHandler;
constructor(private readonly channelControlHelper: ChannelControlHelper) {
this.childBalancer = new ChildLoadBalancerHandler(channelControlHelper);
constructor(private readonly channelControlHelper: ChannelControlHelper, options: ChannelOptions) {
this.childBalancer = new ChildLoadBalancerHandler(channelControlHelper, options);
}
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
if (!(lbConfig instanceof XdsWrrLocalityLoadBalancingConfig)) {
Expand Down
6 changes: 3 additions & 3 deletions packages/grpc-js-xds/test/test-custom-lb-policies.ts
Expand Up @@ -24,7 +24,7 @@ import { XdsServer } 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 { connectivityState, experimental, logVerbosity } from "@grpc/grpc-js";
import { ChannelOptions, connectivityState, experimental, logVerbosity } from "@grpc/grpc-js";

import TypedLoadBalancingConfig = experimental.TypedLoadBalancingConfig;
import LoadBalancer = experimental.LoadBalancer;
Expand Down Expand Up @@ -83,7 +83,7 @@ const RPC_BEHAVIOR_CHILD_CONFIG = parseLoadBalancingConfig({round_robin: {}});
class RpcBehaviorLoadBalancer implements LoadBalancer {
private child: ChildLoadBalancerHandler;
private latestConfig: RpcBehaviorLoadBalancingConfig | null = null;
constructor(channelControlHelper: ChannelControlHelper) {
constructor(channelControlHelper: ChannelControlHelper, options: ChannelOptions) {
const childChannelControlHelper = createChildChannelControlHelper(channelControlHelper, {
updateState: (state, picker) => {
if (state === connectivityState.READY && this.latestConfig) {
Expand All @@ -92,7 +92,7 @@ class RpcBehaviorLoadBalancer implements LoadBalancer {
channelControlHelper.updateState(state, picker);
}
});
this.child = new ChildLoadBalancerHandler(childChannelControlHelper);
this.child = new ChildLoadBalancerHandler(childChannelControlHelper, options);
}
updateAddressList(endpointList: Endpoint[], lbConfig: TypedLoadBalancingConfig, attributes: { [key: string]: unknown; }): void {
if (!(lbConfig instanceof RpcBehaviorLoadBalancingConfig)) {
Expand Down
7 changes: 5 additions & 2 deletions packages/grpc-js/src/load-balancer-child-handler.ts
Expand Up @@ -84,7 +84,10 @@ export class ChildLoadBalancerHandler implements LoadBalancer {
}
};

constructor(private readonly channelControlHelper: ChannelControlHelper) {}
constructor(
private readonly channelControlHelper: ChannelControlHelper,
private readonly options: ChannelOptions
) {}

protected configUpdateRequiresNewPolicyInstance(
oldConfig: TypedLoadBalancingConfig,
Expand All @@ -111,7 +114,7 @@ export class ChildLoadBalancerHandler implements LoadBalancer {
this.configUpdateRequiresNewPolicyInstance(this.latestConfig, lbConfig)
) {
const newHelper = new this.ChildPolicyHelper(this);
const newChild = createLoadBalancer(lbConfig, newHelper)!;
const newChild = createLoadBalancer(lbConfig, newHelper, this.options)!;
newHelper.setChild(newChild);
if (this.currentChild === null) {
this.currentChild = newChild;
Expand Down
8 changes: 6 additions & 2 deletions packages/grpc-js/src/load-balancer-outlier-detection.ts
Expand Up @@ -585,7 +585,10 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer {
private ejectionTimer: NodeJS.Timeout;
private timerStartTime: Date | null = null;

constructor(channelControlHelper: ChannelControlHelper) {
constructor(
channelControlHelper: ChannelControlHelper,
options: ChannelOptions
) {
this.childBalancer = new ChildLoadBalancerHandler(
createChildChannelControlHelper(channelControlHelper, {
createSubchannel: (
Expand Down Expand Up @@ -619,7 +622,8 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer {
channelControlHelper.updateState(connectivityState, picker);
}
},
})
}),
options
);
this.ejectionTimer = setInterval(() => {}, 0);
clearInterval(this.ejectionTimer);
Expand Down
14 changes: 11 additions & 3 deletions packages/grpc-js/src/load-balancer-pick-first.ts
Expand Up @@ -42,6 +42,7 @@ import {
} from './subchannel-interface';
import { isTcpSubchannelAddress } from './subchannel-address';
import { isIPv6 } from 'net';
import { ChannelOptions } from './channel-options';

const TRACER_NAME = 'pick_first';

Expand Down Expand Up @@ -162,6 +163,9 @@ function interleaveAddressFamilies(
return result;
}

const REPORT_HEALTH_STATUS_OPTION_NAME =
'grpc-node.internal.pick-first.report_health_status';

export class PickFirstLoadBalancer implements LoadBalancer {
/**
* The list of subchannels this load balancer is currently attempting to
Expand Down Expand Up @@ -212,6 +216,8 @@ export class PickFirstLoadBalancer implements LoadBalancer {
*/
private stickyTransientFailureMode = false;

private reportHealthStatus: boolean;

/**
* Load balancer that attempts to connect to each backend in the address list
* in order, and picks the first one that connects, using it for every
Expand All @@ -221,10 +227,11 @@ export class PickFirstLoadBalancer implements LoadBalancer {
*/
constructor(
private readonly channelControlHelper: ChannelControlHelper,
private reportHealthStatus = false
options: ChannelOptions
) {
this.connectionDelayTimeout = setTimeout(() => {}, 0);
clearTimeout(this.connectionDelayTimeout);
this.reportHealthStatus = options[REPORT_HEALTH_STATUS_OPTION_NAME];
}

private allChildrenHaveReportedTF(): boolean {
Expand Down Expand Up @@ -510,7 +517,8 @@ export class LeafLoadBalancer {
private latestPicker: Picker;
constructor(
private endpoint: Endpoint,
channelControlHelper: ChannelControlHelper
channelControlHelper: ChannelControlHelper,
options: ChannelOptions
) {
const childChannelControlHelper = createChildChannelControlHelper(
channelControlHelper,
Expand All @@ -524,7 +532,7 @@ export class LeafLoadBalancer {
);
this.pickFirstBalancer = new PickFirstLoadBalancer(
childChannelControlHelper,
/* reportHealthStatus= */ true
{ ...options, [REPORT_HEALTH_STATUS_OPTION_NAME]: true }
);
this.latestPicker = new QueuePicker(this.pickFirstBalancer);
}
Expand Down
13 changes: 11 additions & 2 deletions packages/grpc-js/src/load-balancer-round-robin.ts
Expand Up @@ -38,6 +38,7 @@ import {
endpointToString,
} from './subchannel-address';
import { LeafLoadBalancer } from './load-balancer-pick-first';
import { ChannelOptions } from './channel-options';

const TRACER_NAME = 'round_robin';

Expand Down Expand Up @@ -99,7 +100,10 @@ export class RoundRobinLoadBalancer implements LoadBalancer {

private childChannelControlHelper: ChannelControlHelper;

constructor(private readonly channelControlHelper: ChannelControlHelper) {
constructor(
private readonly channelControlHelper: ChannelControlHelper,
private readonly options: ChannelOptions
) {
this.childChannelControlHelper = createChildChannelControlHelper(
channelControlHelper,
{
Expand Down Expand Up @@ -186,7 +190,12 @@ export class RoundRobinLoadBalancer implements LoadBalancer {
trace('Connect to endpoint list ' + endpointList.map(endpointToString));
this.updatesPaused = true;
this.children = endpointList.map(
endpoint => new LeafLoadBalancer(endpoint, this.childChannelControlHelper)
endpoint =>
new LeafLoadBalancer(
endpoint,
this.childChannelControlHelper,
this.options
)
);
for (const child of this.children) {
child.startConnecting();
Expand Down
11 changes: 8 additions & 3 deletions packages/grpc-js/src/load-balancer.ts
Expand Up @@ -128,7 +128,10 @@ export interface LoadBalancer {
}

export interface LoadBalancerConstructor {
new (channelControlHelper: ChannelControlHelper): LoadBalancer;
new (
channelControlHelper: ChannelControlHelper,
options: ChannelOptions
): LoadBalancer;
}

export interface TypedLoadBalancingConfig {
Expand Down Expand Up @@ -169,12 +172,14 @@ export function registerDefaultLoadBalancerType(typeName: string) {

export function createLoadBalancer(
config: TypedLoadBalancingConfig,
channelControlHelper: ChannelControlHelper
channelControlHelper: ChannelControlHelper,
options: ChannelOptions
): LoadBalancer | null {
const typeName = config.getLoadBalancerName();
if (typeName in registeredLoadBalancerTypes) {
return new registeredLoadBalancerTypes[typeName].LoadBalancer(
channelControlHelper
channelControlHelper,
options
);
} else {
return null;
Expand Down

0 comments on commit 71d8118

Please sign in to comment.