diff --git a/common/lib/aws_client.ts b/common/lib/aws_client.ts index 58e32245..ce124077 100644 --- a/common/lib/aws_client.ts +++ b/common/lib/aws_client.ts @@ -142,10 +142,6 @@ export abstract class AwsClient extends EventEmitter { return await this.pluginService.isClientValid(this.targetClient); } - async releaseResources(): Promise { - await this.pluginManager.releaseResources(); - } - getPluginInstance(iface: any): T { return this.pluginManager.getPluginInstance(iface); } diff --git a/common/lib/plugin_manager.ts b/common/lib/plugin_manager.ts index b06ec6cb..6cbd2b29 100644 --- a/common/lib/plugin_manager.ts +++ b/common/lib/plugin_manager.ts @@ -70,6 +70,7 @@ export class PluginManager { private static readonly NOTIFY_CONNECTION_CHANGED_METHOD: string = "notifyConnectionChanged"; private static readonly ACCEPTS_STRATEGY_METHOD: string = "acceptsStrategy"; private static readonly GET_HOST_INFO_BY_STRATEGY_METHOD: string = "getHostInfoByStrategy"; + private static PLUGINS: Set = new Set(); private readonly props: Map; private _plugins: ConnectionPlugin[] = []; private readonly connectionProviderManager: ConnectionProviderManager; @@ -103,6 +104,9 @@ export class PluginManager { ); } } + for (const plugin of this._plugins) { + PluginManager.PLUGINS.add(plugin); + } } runMethodFuncWithTelemetry(methodFunc: () => Promise, name: string): Promise { @@ -302,22 +306,23 @@ export class PluginManager { throw new AwsWrapperError("The driver does not support the requested host selection strategy: " + strategy); } - async releaseResources() { + static async releaseResources() { // This step allows all connection plugins a chance to clean up any dangling resources or // perform any last tasks before shutting down. - for (const plugin of this._plugins) { - if (this.implementsCanReleaseResources(plugin)) { + for (const plugin of PluginManager.PLUGINS) { + if (PluginManager.implementsCanReleaseResources(plugin)) { await plugin.releaseResources(); } } + PluginManager.PLUGINS = new Set(); } getConnectionProvider(hostInfo: HostInfo | null, props: Map): ConnectionProvider { return this.connectionProviderManager.getConnectionProvider(hostInfo, props); } - private implementsCanReleaseResources(plugin: any): plugin is CanReleaseResources { + private static implementsCanReleaseResources(plugin: any): plugin is CanReleaseResources { return plugin.releaseResources !== undefined; } diff --git a/mysql/lib/client.ts b/mysql/lib/client.ts index 2e0e17e3..2955c17e 100644 --- a/mysql/lib/client.ts +++ b/mysql/lib/client.ts @@ -31,6 +31,7 @@ import { ClientUtils } from "../../common/lib/utils/client_utils"; import { RdsMultiAZMySQLDatabaseDialect } from "./dialect/rds_multi_az_mysql_database_dialect"; import { TelemetryTraceLevel } from "../../common/lib/utils/telemetry/telemetry_trace_level"; import { MySQL2DriverDialect } from "./dialect/mysql2_driver_dialect"; +import { PluginManager } from "../../common/lib"; export class AwsMySQLClient extends AwsClient { private static readonly knownDialectsByCode: Map = new Map([ @@ -212,7 +213,6 @@ export class AwsMySQLClient extends AwsClient { }, null ); - await this.releaseResources(); return result; } diff --git a/pg/lib/client.ts b/pg/lib/client.ts index a836e9b9..0138e7ad 100644 --- a/pg/lib/client.ts +++ b/pg/lib/client.ts @@ -189,7 +189,6 @@ export class AwsPGClient extends AwsClient { }, null ); - await this.releaseResources(); return result; } diff --git a/tests/integration/container/tests/aurora_failover.test.ts b/tests/integration/container/tests/aurora_failover.test.ts index 5dfbb3db..d425c378 100644 --- a/tests/integration/container/tests/aurora_failover.test.ts +++ b/tests/integration/container/tests/aurora_failover.test.ts @@ -25,6 +25,7 @@ import { RdsUtils } from "../../../../common/lib/utils/rds_utils"; import { logger } from "../../../../common/logutils"; import { features, instanceCount } from "./config"; import { TestEnvironmentFeatures } from "./utils/test_environment_features"; +import { PluginManager } from "../../../../common/lib"; const itIf = features.includes(TestEnvironmentFeatures.FAILOVER_SUPPORTED) && @@ -94,6 +95,7 @@ describe("aurora failover", () => { // pass } } + await PluginManager.releaseResources(); logger.info(`Test finished: ${expect.getState().currentTestName}`); }, 1320000); diff --git a/tests/integration/container/tests/autoscaling.test.ts b/tests/integration/container/tests/autoscaling.test.ts index bf690c17..25435a32 100644 --- a/tests/integration/container/tests/autoscaling.test.ts +++ b/tests/integration/container/tests/autoscaling.test.ts @@ -26,6 +26,7 @@ import { ConnectionProviderManager } from "../../../../common/lib/connection_pro import { TestInstanceInfo } from "./utils/test_instance_info"; import { sleep } from "../../../../common/lib/utils/utils"; import { FailoverSuccessError } from "../../../../common/lib/utils/errors"; +import { PluginManager } from "../../../../common/lib"; const itIf = !features.includes(TestEnvironmentFeatures.PERFORMANCE) && @@ -109,6 +110,7 @@ describe("pooled connection autoscaling", () => { // pass } } + await PluginManager.releaseResources(); logger.info(`Test finished: ${expect.getState().currentTestName}`); }, 1320000); diff --git a/tests/integration/container/tests/basic_connectivity.test.ts b/tests/integration/container/tests/basic_connectivity.test.ts index 6b2c4828..979027f7 100644 --- a/tests/integration/container/tests/basic_connectivity.test.ts +++ b/tests/integration/container/tests/basic_connectivity.test.ts @@ -23,6 +23,7 @@ import { DatabaseEngine } from "./utils/database_engine"; import { TestEnvironmentFeatures } from "./utils/test_environment_features"; import { features } from "./config"; import { DatabaseEngineDeployment } from "./utils/database_engine_deployment"; +import { PluginManager } from "../../../../common/lib"; const itIf = !features.includes(TestEnvironmentFeatures.PERFORMANCE) && !features.includes(TestEnvironmentFeatures.RUN_AUTOSCALING_TESTS_ONLY) ? it : it.skip; @@ -54,6 +55,7 @@ afterEach(async () => { // pass } } + await PluginManager.releaseResources(); logger.info(`Test finished: ${expect.getState().currentTestName}`); }, 1320000); diff --git a/tests/integration/container/tests/iam_authentication.test.ts b/tests/integration/container/tests/iam_authentication.test.ts index cf7c976b..94540e95 100644 --- a/tests/integration/container/tests/iam_authentication.test.ts +++ b/tests/integration/container/tests/iam_authentication.test.ts @@ -26,6 +26,7 @@ import { IamAuthenticationPlugin } from "../../../../common/lib/authentication/i import { logger } from "../../../../common/logutils"; import { TestEnvironmentFeatures } from "./utils/test_environment_features"; import { features } from "./config"; +import { PluginManager } from "../../../../common/lib"; const itIf = !features.includes(TestEnvironmentFeatures.PERFORMANCE) && @@ -89,6 +90,7 @@ describe("iam authentication", () => { }); afterEach(async () => { + await PluginManager.releaseResources(); await TestEnvironment.verifyClusterStatus(); logger.info(`Test finished: ${expect.getState().currentTestName}`); }, 1320000); diff --git a/tests/integration/container/tests/performance.test.ts b/tests/integration/container/tests/performance.test.ts index 37bd586d..5d7c47f7 100644 --- a/tests/integration/container/tests/performance.test.ts +++ b/tests/integration/container/tests/performance.test.ts @@ -26,6 +26,7 @@ import { features } from "./config"; import { MonitorServiceImpl } from "../../../../common/lib/plugins/efm/monitor_service"; import { PerfStat } from "./utils/perf_stat"; import { PerfTestUtility } from "./utils/perf_util"; +import { PluginManager } from "../../../../common/lib"; const itIf = features.includes(TestEnvironmentFeatures.FAILOVER_SUPPORTED) && @@ -253,6 +254,7 @@ describe("performance", () => { }); afterEach(async () => { + await PluginManager.releaseResources(); await TestEnvironment.verifyClusterStatus(); logger.info(`Test finished: ${expect.getState().currentTestName}`); }, 1320000); diff --git a/tests/integration/container/tests/read_write_splitting.test.ts b/tests/integration/container/tests/read_write_splitting.test.ts index 39bad76b..88acdb97 100644 --- a/tests/integration/container/tests/read_write_splitting.test.ts +++ b/tests/integration/container/tests/read_write_splitting.test.ts @@ -29,6 +29,7 @@ import { AwsPoolConfig } from "../../../../common/lib/aws_pool_config"; import { ConnectionProviderManager } from "../../../../common/lib/connection_provider_manager"; import { InternalPoolMapping } from "../../../../common/lib/utils/internal_pool_mapping"; import { HostInfo } from "../../../../common/lib/host_info"; +import { PluginManager } from "../../../../common/lib"; const itIf = !features.includes(TestEnvironmentFeatures.PERFORMANCE) && @@ -121,6 +122,7 @@ describe("aurora read write splitting", () => { // pass } } + await PluginManager.releaseResources(); logger.info(`Test finished: ${expect.getState().currentTestName}`); }, 1320000); diff --git a/tests/integration/container/tests/read_write_splitting_performance.test.ts b/tests/integration/container/tests/read_write_splitting_performance.test.ts index 2915055c..5961e3ab 100644 --- a/tests/integration/container/tests/read_write_splitting_performance.test.ts +++ b/tests/integration/container/tests/read_write_splitting_performance.test.ts @@ -26,6 +26,7 @@ import { ExecuteTimePlugin } from "../../../../common/lib/plugins/execute_time_p import { TestDriver } from "./utils/test_driver"; import { ConnectionProviderManager } from "../../../../common/lib/connection_provider_manager"; import { InternalPooledConnectionProvider } from "../../../../common/lib/internal_pooled_connection_provider"; +import { PluginManager } from "../../../../common/lib"; const itIf = features.includes(TestEnvironmentFeatures.FAILOVER_SUPPORTED) && @@ -52,6 +53,7 @@ describe("rwperformance", () => { }); afterEach(async () => { + await PluginManager.releaseResources(); logger.info(`Test finished: ${expect.getState().currentTestName}`); }, 1320000); diff --git a/tests/plugin_benchmarks.ts b/tests/plugin_benchmarks.ts index 18b0110b..07cacb5e 100644 --- a/tests/plugin_benchmarks.ts +++ b/tests/plugin_benchmarks.ts @@ -78,7 +78,7 @@ suite( const pluginManager = getPluginManager(props); const wrapper = new TestConnectionWrapper(props, pluginManager, instance(mockPluginService)); await pluginManager.init(); - await wrapper.releaseResources(); + await PluginManager.releaseResources(); }), add("initAndReleaseWithExecuteTimePlugin", async () => { @@ -86,7 +86,7 @@ suite( const pluginManager = getPluginManager(props); const wrapper = new TestConnectionWrapper(props, pluginManager, instance(mockPluginService)); await pluginManager.init(); - await wrapper.releaseResources(); + await PluginManager.releaseResources(); }), add("initAndReleaseWithReadWriteSplittingPlugin", async () => { @@ -94,7 +94,7 @@ suite( const pluginManager = getPluginManager(props); const wrapper = new TestConnectionWrapper(props, pluginManager, instance(mockPluginService)); await pluginManager.init(); - await wrapper.releaseResources(); + await PluginManager.releaseResources(); }), add("executeStatementBaseline", async () => { diff --git a/tests/plugin_manager_benchmarks.ts b/tests/plugin_manager_benchmarks.ts index ce38c767..4bc22e17 100644 --- a/tests/plugin_manager_benchmarks.ts +++ b/tests/plugin_manager_benchmarks.ts @@ -350,37 +350,37 @@ suite( add("releaseResourcesWithNoPlugins", async () => { const pluginManagerWithNoPlugins = getPluginManagerWithNoPlugins(); await pluginManagerWithNoPlugins.init(); - return async () => await pluginManagerWithNoPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), add("releaseResourcesWith1Plugins", async () => { const pluginManagerWithPlugins = getPluginManagerWithPlugins(); await pluginManagerWithPlugins.init(await createPlugins(1, instance(mockPluginService), instance(mockConnectionProvider), propsWithPlugins)); - return async () => await pluginManagerWithPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), add("releaseResourcesWith2Plugins", async () => { const pluginManagerWithPlugins = getPluginManagerWithPlugins(); await pluginManagerWithPlugins.init(await createPlugins(2, instance(mockPluginService), instance(mockConnectionProvider), propsWithPlugins)); - return async () => await pluginManagerWithPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), add("releaseResourcesWith5Plugins", async () => { const pluginManagerWithPlugins = getPluginManagerWithPlugins(); await pluginManagerWithPlugins.init(await createPlugins(5, instance(mockPluginService), instance(mockConnectionProvider), propsWithPlugins)); - return async () => await pluginManagerWithPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), add("releaseResourcesWith10Plugins", async () => { const pluginManagerWithPlugins = getPluginManagerWithPlugins(); await pluginManagerWithPlugins.init(await createPlugins(10, instance(mockPluginService), instance(mockConnectionProvider), propsWithPlugins)); - return async () => await pluginManagerWithPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), add.only("releaseResourcesWithDefaultPlugins", async () => { const pluginManagerWithPlugins = getPluginManagerWithPlugins(); await pluginManagerWithPlugins.init(); - return async () => await pluginManagerWithPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), cycle(), diff --git a/tests/plugin_manager_telemetry_benchmarks.ts b/tests/plugin_manager_telemetry_benchmarks.ts index 1ef2d99e..c96ffc1a 100644 --- a/tests/plugin_manager_telemetry_benchmarks.ts +++ b/tests/plugin_manager_telemetry_benchmarks.ts @@ -410,37 +410,37 @@ suite( add("releaseResourcesWithNoPlugins", async () => { const pluginManagerWithNoPlugins = getPluginManagerWithNoPlugins(); await pluginManagerWithNoPlugins.init(); - return async () => await pluginManagerWithNoPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), add("releaseResourcesWith1Plugins", async () => { const pluginManagerWithPlugins = getPluginManagerWithPlugins(); await pluginManagerWithPlugins.init(await createPlugins(1, instance(mockPluginService), instance(mockConnectionProvider), propsWithPlugins)); - return async () => await pluginManagerWithPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), add("releaseResourcesWith2Plugins", async () => { const pluginManagerWithPlugins = getPluginManagerWithPlugins(); await pluginManagerWithPlugins.init(await createPlugins(2, instance(mockPluginService), instance(mockConnectionProvider), propsWithPlugins)); - return async () => await pluginManagerWithPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), add("releaseResourcesWith5Plugins", async () => { const pluginManagerWithPlugins = getPluginManagerWithPlugins(); await pluginManagerWithPlugins.init(await createPlugins(5, instance(mockPluginService), instance(mockConnectionProvider), propsWithPlugins)); - return async () => await pluginManagerWithPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), add("releaseResourcesWith10Plugins", async () => { const pluginManagerWithPlugins = getPluginManagerWithPlugins(); await pluginManagerWithPlugins.init(await createPlugins(10, instance(mockPluginService), instance(mockConnectionProvider), propsWithPlugins)); - return async () => await pluginManagerWithPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), add.only("releaseResourcesWithDefaultPlugins", async () => { const pluginManagerWithPlugins = getPluginManagerWithPlugins(); await pluginManagerWithPlugins.init(); - return async () => await pluginManagerWithPlugins.releaseResources(); + return async () => await PluginManager.releaseResources(); }), cycle(), diff --git a/tests/plugin_telemetry_benchmarks.ts b/tests/plugin_telemetry_benchmarks.ts index a395ddb2..5b052b71 100644 --- a/tests/plugin_telemetry_benchmarks.ts +++ b/tests/plugin_telemetry_benchmarks.ts @@ -154,21 +154,21 @@ suite( add("initAndReleaseBaseline", async () => { const wrapper = new TestConnectionWrapper(props, pluginManager, instance(mockPluginService)); await pluginManager.init(); - await wrapper.releaseResources(); + await PluginManager.releaseResources(); await wrapper.end(); }), add("initAndReleaseWithExecuteTimePlugin", async () => { const wrapper = new TestConnectionWrapper(propsExecute, pluginManagerExecute, instance(mockPluginService)); await pluginManagerExecute.init(); - await wrapper.releaseResources(); + await PluginManager.releaseResources(); await wrapper.end(); }), add("initAndReleaseWithReadWriteSplittingPlugin", async () => { const wrapper = new TestConnectionWrapper(propsReadWrite, pluginManagerReadWrite, instance(mockPluginService)); await pluginManagerReadWrite.init(); - await wrapper.releaseResources(); + await PluginManager.releaseResources(); await wrapper.end(); }),