Don't unregister the xds server's channelz ref when destroying the connection injector

This commit is contained in:
Michael Lumish 2025-02-27 10:51:00 -08:00
parent 510d68140b
commit 0ebb571bb7
2 changed files with 15 additions and 5 deletions

View File

@ -83,6 +83,7 @@ interface ConfigParameters {
createConnectionInjector: (credentials: ServerCredentials) => ConnectionInjector; createConnectionInjector: (credentials: ServerCredentials) => ConnectionInjector;
drainGraceTimeMs: number; drainGraceTimeMs: number;
listenerResourceNameTemplate: string; listenerResourceNameTemplate: string;
unregisterChannelzRef: () => void;
} }
class FilterChainEntry { class FilterChainEntry {
@ -452,6 +453,7 @@ class BoundPortEntry {
this.tcpServer.close(); this.tcpServer.close();
const resourceName = formatTemplateString(this.configParameters.listenerResourceNameTemplate, this.boundAddress); const resourceName = formatTemplateString(this.configParameters.listenerResourceNameTemplate, this.boundAddress);
ListenerResourceType.cancelWatch(this.configParameters.xdsClient, resourceName, this.listenerWatcher); ListenerResourceType.cancelWatch(this.configParameters.xdsClient, resourceName, this.listenerWatcher);
this.configParameters.unregisterChannelzRef();
} }
} }
@ -633,7 +635,8 @@ export class XdsServer extends Server {
createConnectionInjector: (credentials) => this.experimentalCreateConnectionInjectorWithChannelzRef(credentials, channelzRef), createConnectionInjector: (credentials) => this.experimentalCreateConnectionInjectorWithChannelzRef(credentials, channelzRef),
drainGraceTimeMs: this.drainGraceTimeMs, drainGraceTimeMs: this.drainGraceTimeMs,
listenerResourceNameTemplate: this.listenerResourceNameTemplate, listenerResourceNameTemplate: this.listenerResourceNameTemplate,
xdsClient: this.xdsClient xdsClient: this.xdsClient,
unregisterChannelzRef: () => this.experimentalUnregisterListenerFromChannelz(channelzRef)
}; };
const portEntry = new BoundPortEntry(configParameters, port, creds); const portEntry = new BoundPortEntry(configParameters, port, creds);
const servingStatusListener: ServingStatusListener = statusObject => { const servingStatusListener: ServingStatusListener = statusObject => {

View File

@ -246,6 +246,7 @@ interface BoundPort {
interface Http2ServerInfo { interface Http2ServerInfo {
channelzRef: SocketRef; channelzRef: SocketRef;
sessions: Set<http2.ServerHttp2Session>; sessions: Set<http2.ServerHttp2Session>;
ownsChannelzRef: boolean;
} }
interface SessionIdleTimeoutTracker { interface SessionIdleTimeoutTracker {
@ -571,6 +572,10 @@ export class Server {
); );
} }
protected experimentalUnregisterListenerFromChannelz(channelzRef: SocketRef) {
unregisterChannelzRef(channelzRef);
}
private createHttp2Server(credentials: ServerCredentials) { private createHttp2Server(credentials: ServerCredentials) {
let http2Server: http2.Http2Server | http2.Http2SecureServer; let http2Server: http2.Http2Server | http2.Http2SecureServer;
if (credentials._isSecure()) { if (credentials._isSecure()) {
@ -670,6 +675,7 @@ export class Server {
this.http2Servers.set(http2Server, { this.http2Servers.set(http2Server, {
channelzRef: channelzRef, channelzRef: channelzRef,
sessions: new Set(), sessions: new Set(),
ownsChannelzRef: true
}); });
boundPortObject.listeningServers.add(http2Server); boundPortObject.listeningServers.add(http2Server);
this.trace( this.trace(
@ -964,7 +970,7 @@ export class Server {
* @param channelzRef * @param channelzRef
* @returns * @returns
*/ */
protected experimentalCreateConnectionInjectorWithChannelzRef(credentials: ServerCredentials, channelzRef: SocketRef) { protected experimentalCreateConnectionInjectorWithChannelzRef(credentials: ServerCredentials, channelzRef: SocketRef, ownsChannelzRef=false) {
if (credentials === null || !(credentials instanceof ServerCredentials)) { if (credentials === null || !(credentials instanceof ServerCredentials)) {
throw new TypeError('creds must be a ServerCredentials object'); throw new TypeError('creds must be a ServerCredentials object');
} }
@ -975,7 +981,8 @@ export class Server {
const sessionsSet: Set<http2.ServerHttp2Session> = new Set(); const sessionsSet: Set<http2.ServerHttp2Session> = new Set();
this.http2Servers.set(server, { this.http2Servers.set(server, {
channelzRef: channelzRef, channelzRef: channelzRef,
sessions: sessionsSet sessions: sessionsSet,
ownsChannelzRef
}); });
return { return {
injectConnection: (connection: Duplex) => { injectConnection: (connection: Duplex) => {
@ -1005,7 +1012,7 @@ export class Server {
throw new TypeError('creds must be a ServerCredentials object'); throw new TypeError('creds must be a ServerCredentials object');
} }
const channelzRef = this.registerInjectorToChannelz(); const channelzRef = this.registerInjectorToChannelz();
return this.experimentalCreateConnectionInjectorWithChannelzRef(credentials, channelzRef); return this.experimentalCreateConnectionInjectorWithChannelzRef(credentials, channelzRef, true);
} }
private closeServer(server: AnyHttp2Server, callback?: () => void) { private closeServer(server: AnyHttp2Server, callback?: () => void) {
@ -1014,7 +1021,7 @@ export class Server {
); );
const serverInfo = this.http2Servers.get(server); const serverInfo = this.http2Servers.get(server);
server.close(() => { server.close(() => {
if (serverInfo) { if (serverInfo && serverInfo.ownsChannelzRef) {
this.listenerChildrenTracker.unrefChild(serverInfo.channelzRef); this.listenerChildrenTracker.unrefChild(serverInfo.channelzRef);
unregisterChannelzRef(serverInfo.channelzRef); unregisterChannelzRef(serverInfo.channelzRef);
} }