grpc-js: Refactor FilterStack usage

This commit is contained in:
Michael Lumish 2021-06-10 14:48:33 -07:00
parent 47ac924abe
commit 8a38cd8549
10 changed files with 28 additions and 38 deletions

View File

@ -37,7 +37,6 @@ import { Watcher } from './xds-stream-state/xds-stream-state';
import Filter = experimental.Filter; import Filter = experimental.Filter;
import BaseFilter = experimental.BaseFilter; import BaseFilter = experimental.BaseFilter;
import FilterFactory = experimental.FilterFactory; import FilterFactory = experimental.FilterFactory;
import FilterStackFactory = experimental.FilterStackFactory;
import CallStream = experimental.CallStream; import CallStream = experimental.CallStream;
const TRACER_NAME = 'eds_balancer'; const TRACER_NAME = 'eds_balancer';
@ -206,12 +205,9 @@ export class EdsLoadBalancer implements LoadBalancer {
* balancer. */ * balancer. */
if (dropCategory === null) { if (dropCategory === null) {
const originalPick = originalPicker.pick(pickArgs); const originalPick = originalPicker.pick(pickArgs);
let extraFilterFactory: FilterFactory<Filter> = new CallTrackingFilterFactory(() => { const trackingFilterFactory: FilterFactory<Filter> = new CallTrackingFilterFactory(() => {
this.concurrentRequests -= 1; this.concurrentRequests -= 1;
}); });
if (originalPick.extraFilterFactory) {
extraFilterFactory = new FilterStackFactory([originalPick.extraFilterFactory, extraFilterFactory]);
}
return { return {
pickResultType: originalPick.pickResultType, pickResultType: originalPick.pickResultType,
status: originalPick.status, status: originalPick.status,
@ -220,7 +216,7 @@ export class EdsLoadBalancer implements LoadBalancer {
originalPick.onCallStarted?.(); originalPick.onCallStarted?.();
this.concurrentRequests += 1; this.concurrentRequests += 1;
}, },
extraFilterFactory: extraFilterFactory extraFilterFactories: originalPick.extraFilterFactories.concat(trackingFilterFactory)
}; };
} else { } else {
let details: string; let details: string;
@ -239,7 +235,7 @@ export class EdsLoadBalancer implements LoadBalancer {
metadata: new Metadata(), metadata: new Metadata(),
}, },
subchannel: null, subchannel: null,
extraFilterFactory: null, extraFilterFactories: [],
onCallStarted: null onCallStarted: null
}; };
} }

View File

@ -32,7 +32,6 @@ import PickResult = experimental.PickResult;
import Filter = experimental.Filter; import Filter = experimental.Filter;
import BaseFilter = experimental.BaseFilter; import BaseFilter = experimental.BaseFilter;
import FilterFactory = experimental.FilterFactory; import FilterFactory = experimental.FilterFactory;
import FilterStackFactory = experimental.FilterStackFactory;
import Call = experimental.CallStream; import Call = experimental.CallStream;
import validateLoadBalancingConfig = experimental.validateLoadBalancingConfig import validateLoadBalancingConfig = experimental.validateLoadBalancingConfig
@ -148,14 +147,6 @@ class LoadReportingPicker implements Picker {
const trackingFilterFactory = new CallEndTrackingFilterFactory( const trackingFilterFactory = new CallEndTrackingFilterFactory(
this.localityStatsReporter this.localityStatsReporter
); );
/* In the unlikely event that the wrappedPick already has an
* extraFilterFactory, preserve it in a FilterStackFactory. */
const extraFilterFactory = wrappedPick.extraFilterFactory
? new FilterStackFactory([
wrappedPick.extraFilterFactory,
trackingFilterFactory,
])
: trackingFilterFactory;
return { return {
pickResultType: PickResultType.COMPLETE, pickResultType: PickResultType.COMPLETE,
subchannel: wrappedPick.subchannel, subchannel: wrappedPick.subchannel,
@ -164,7 +155,7 @@ class LoadReportingPicker implements Picker {
wrappedPick.onCallStarted?.(); wrappedPick.onCallStarted?.();
this.localityStatsReporter.addCallStarted(); this.localityStatsReporter.addCallStarted();
}, },
extraFilterFactory: extraFilterFactory, extraFilterFactories: wrappedPick.extraFilterFactories.concat(trackingFilterFactory),
}; };
} else { } else {
return wrappedPick; return wrappedPick;

View File

@ -107,7 +107,7 @@ class XdsClusterManagerPicker implements Picker {
metadata: new Metadata(), metadata: new Metadata(),
}, },
subchannel: null, subchannel: null,
extraFilterFactory: null, extraFilterFactories: [],
onCallStarted: null onCallStarted: null
}; };
} }

View File

@ -210,7 +210,7 @@ export interface Call {
export class Http2CallStream implements Call { export class Http2CallStream implements Call {
credentials: CallCredentials; credentials: CallCredentials;
filterStack: Filter; filterStack: FilterStack;
private http2Stream: http2.ClientHttp2Stream | null = null; private http2Stream: http2.ClientHttp2Stream | null = null;
private pendingRead = false; private pendingRead = false;
private isWriteFilterPending = false; private isWriteFilterPending = false;
@ -462,14 +462,9 @@ export class Http2CallStream implements Call {
attachHttp2Stream( attachHttp2Stream(
stream: http2.ClientHttp2Stream, stream: http2.ClientHttp2Stream,
subchannel: Subchannel, subchannel: Subchannel,
extraFilterFactory?: FilterFactory<Filter> extraFilters: FilterFactory<Filter>[]
): void { ): void {
if (extraFilterFactory !== undefined) { this.filterStack.push(extraFilters.map(filterFactory => filterFactory.createFilter(this)));
this.filterStack = new FilterStack([
this.filterStack,
extraFilterFactory.createFilter(this),
]);
}
if (this.finalStatus !== null) { if (this.finalStatus !== null) {
stream.close(NGHTTP2_CANCEL); stream.close(NGHTTP2_CANCEL);
} else { } else {

View File

@ -373,7 +373,7 @@ export class ChannelImplementation implements Channel {
pickResult.subchannel!.startCallStream( pickResult.subchannel!.startCallStream(
finalMetadata, finalMetadata,
callStream, callStream,
pickResult.extraFilterFactory ?? undefined pickResult.extraFilterFactories
); );
/* If we reach this point, the call stream has started /* If we reach this point, the call stream has started
* successfully */ * successfully */

View File

@ -77,11 +77,19 @@ export class FilterStack implements Filter {
filter.refresh(); filter.refresh();
} }
} }
push(filters: Filter[]) {
this.filters.unshift(...filters);
}
} }
export class FilterStackFactory implements FilterFactory<FilterStack> { export class FilterStackFactory implements FilterFactory<FilterStack> {
constructor(private readonly factories: Array<FilterFactory<Filter>>) {} constructor(private readonly factories: Array<FilterFactory<Filter>>) {}
push(filterFactories: FilterFactory<Filter>[]) {
this.factories.unshift(...filterFactories);
}
createFilter(callStream: Call): FilterStack { createFilter(callStream: Call): FilterStack {
return new FilterStack( return new FilterStack(
this.factories.map((factory) => factory.createFilter(callStream)) this.factories.map((factory) => factory.createFilter(callStream))

View File

@ -83,7 +83,7 @@ class PickFirstPicker implements Picker {
pickResultType: PickResultType.COMPLETE, pickResultType: PickResultType.COMPLETE,
subchannel: this.subchannel, subchannel: this.subchannel,
status: null, status: null,
extraFilterFactory: null, extraFilterFactories: [],
onCallStarted: null, onCallStarted: null,
}; };
} }

View File

@ -78,7 +78,7 @@ class RoundRobinPicker implements Picker {
pickResultType: PickResultType.COMPLETE, pickResultType: PickResultType.COMPLETE,
subchannel: pickedSubchannel, subchannel: pickedSubchannel,
status: null, status: null,
extraFilterFactory: null, extraFilterFactories: [],
onCallStarted: null, onCallStarted: null,
}; };
} }

View File

@ -47,7 +47,7 @@ export interface PickResult {
* provided by the load balancer to be used with the call. For technical * provided by the load balancer to be used with the call. For technical
* reasons filters from this factory will not see sendMetadata events. * reasons filters from this factory will not see sendMetadata events.
*/ */
extraFilterFactory: FilterFactory<Filter> | null; extraFilterFactories: FilterFactory<Filter>[];
onCallStarted: (() => void) | null; onCallStarted: (() => void) | null;
} }
@ -55,7 +55,7 @@ export interface CompletePickResult extends PickResult {
pickResultType: PickResultType.COMPLETE; pickResultType: PickResultType.COMPLETE;
subchannel: Subchannel | null; subchannel: Subchannel | null;
status: null; status: null;
extraFilterFactory: FilterFactory<Filter> | null; extraFilterFactories: FilterFactory<Filter>[];
onCallStarted: (() => void) | null; onCallStarted: (() => void) | null;
} }
@ -63,7 +63,7 @@ export interface QueuePickResult extends PickResult {
pickResultType: PickResultType.QUEUE; pickResultType: PickResultType.QUEUE;
subchannel: null; subchannel: null;
status: null; status: null;
extraFilterFactory: null; extraFilterFactories: [];
onCallStarted: null; onCallStarted: null;
} }
@ -71,7 +71,7 @@ export interface TransientFailurePickResult extends PickResult {
pickResultType: PickResultType.TRANSIENT_FAILURE; pickResultType: PickResultType.TRANSIENT_FAILURE;
subchannel: null; subchannel: null;
status: StatusObject; status: StatusObject;
extraFilterFactory: null; extraFilterFactories: [];
onCallStarted: null; onCallStarted: null;
} }
@ -79,7 +79,7 @@ export interface DropCallPickResult extends PickResult {
pickResultType: PickResultType.DROP; pickResultType: PickResultType.DROP;
subchannel: null; subchannel: null;
status: StatusObject; status: StatusObject;
extraFilterFactory: null; extraFilterFactories: [];
onCallStarted: null; onCallStarted: null;
} }
@ -119,7 +119,7 @@ export class UnavailablePicker implements Picker {
pickResultType: PickResultType.TRANSIENT_FAILURE, pickResultType: PickResultType.TRANSIENT_FAILURE,
subchannel: null, subchannel: null,
status: this.status, status: this.status,
extraFilterFactory: null, extraFilterFactories: [],
onCallStarted: null, onCallStarted: null,
}; };
} }
@ -148,7 +148,7 @@ export class QueuePicker {
pickResultType: PickResultType.QUEUE, pickResultType: PickResultType.QUEUE,
subchannel: null, subchannel: null,
status: null, status: null,
extraFilterFactory: null, extraFilterFactories: [],
onCallStarted: null, onCallStarted: null,
}; };
} }

View File

@ -688,7 +688,7 @@ export class Subchannel {
startCallStream( startCallStream(
metadata: Metadata, metadata: Metadata,
callStream: Http2CallStream, callStream: Http2CallStream,
extraFilterFactory?: FilterFactory<Filter> extraFilterFactories: FilterFactory<Filter>[]
) { ) {
const headers = metadata.toHttp2Headers(); const headers = metadata.toHttp2Headers();
headers[HTTP2_HEADER_AUTHORITY] = callStream.getHost(); headers[HTTP2_HEADER_AUTHORITY] = callStream.getHost();
@ -720,7 +720,7 @@ export class Subchannel {
headersString += '\t\t' + header + ': ' + headers[header] + '\n'; headersString += '\t\t' + header + ': ' + headers[header] + '\n';
} }
logging.trace(LogVerbosity.DEBUG, 'call_stream', 'Starting stream on subchannel ' + this.subchannelAddressString + ' with headers\n' + headersString); logging.trace(LogVerbosity.DEBUG, 'call_stream', 'Starting stream on subchannel ' + this.subchannelAddressString + ' with headers\n' + headersString);
callStream.attachHttp2Stream(http2Stream, this, extraFilterFactory); callStream.attachHttp2Stream(http2Stream, this, extraFilterFactories);
} }
/** /**