diff --git a/common/lib/aws_pool_client.ts b/common/lib/aws_pool_client.ts index c9d5da8b..b5f0e238 100644 --- a/common/lib/aws_pool_client.ts +++ b/common/lib/aws_pool_client.ts @@ -19,7 +19,7 @@ export interface AwsPoolClient { end(poolClient: any): Promise; - releaseResources(): void; + releaseResources(): Promise; getIdleCount(): number; diff --git a/common/lib/aws_pool_config.ts b/common/lib/aws_pool_config.ts index fd7a35d0..7388aa1f 100644 --- a/common/lib/aws_pool_config.ts +++ b/common/lib/aws_pool_config.ts @@ -18,14 +18,12 @@ export class AwsPoolConfig { readonly maxConnections?: number | undefined; readonly minConnections?: number | undefined; readonly idleTimeoutMillis?: number | undefined; - readonly connectionTimeoutMillis?: number | undefined; readonly allowExitOnIdle?: boolean | undefined; readonly maxIdleConnections?: number | undefined; constructor(props?: any) { this.maxConnections = props.maxConnections ?? 10; this.idleTimeoutMillis = props.idleTimeoutMillis ?? 60000; - this.connectionTimeoutMillis = props.connectionTimeoutMillis ?? 60000; this.maxIdleConnections = props.maxIdleConnections ?? 10; this.allowExitOnIdle = props.allowExitOnIdle ?? false; this.minConnections = props.minConnections ?? 0; diff --git a/common/lib/internal_pooled_connection_provider.ts b/common/lib/internal_pooled_connection_provider.ts index 2c577eda..ebb62794 100644 --- a/common/lib/internal_pooled_connection_provider.ts +++ b/common/lib/internal_pooled_connection_provider.ts @@ -133,7 +133,9 @@ export class InternalPooledConnectionProvider implements PooledConnectionProvide } public async releaseResources() { - this.internalPool?.releaseResources(); + for (const [key, val] of this.databasePools.entries) { + val.item.releaseResources(); + } this.databasePools.clear(); } @@ -151,7 +153,7 @@ export class InternalPooledConnectionProvider implements PooledConnectionProvide getHostUrlSet(): Set { const hostUrls: Set = new Set(); - for (const [key, val] of this.databasePools.entries) { + for (const [key, _val] of this.databasePools.entries) { hostUrls.add(key.getUrl()); } return hostUrls; @@ -186,8 +188,4 @@ export class InternalPooledConnectionProvider implements PooledConnectionProvide setDatabasePools(connectionPools: SlidingExpirationCache): void { this.databasePools = connectionPools; } - - getTargetName(): string { - return this.constructor.name; - } } diff --git a/mysql/lib/dialect/mysql_database_dialect.ts b/mysql/lib/dialect/mysql_database_dialect.ts index d5571d2d..ac254213 100644 --- a/mysql/lib/dialect/mysql_database_dialect.ts +++ b/mysql/lib/dialect/mysql_database_dialect.ts @@ -199,7 +199,7 @@ export class MySQLDatabaseDialect implements DatabaseDialect { return finalPoolConfig; } - end(clientWrapper: ClientWrapper): Promise { - return clientWrapper.client.end(); + async end(clientWrapper: ClientWrapper): Promise { + return await clientWrapper.client.end(); } } diff --git a/mysql/lib/mysql_error_handler.ts b/mysql/lib/mysql_error_handler.ts index 48e60ab3..812425bb 100644 --- a/mysql/lib/mysql_error_handler.ts +++ b/mysql/lib/mysql_error_handler.ts @@ -27,7 +27,9 @@ export class MySQLErrorHandler implements ErrorHandler { e.message.includes("Connection lost: The server closed the connection.") || e.message.includes("Query inactivity timeout") || e.message.includes("Can't add new command when connection is in closed state") || - e.message.includes(Messages.get("ClientUtils.queryTaskTimeout")) + e.message.includes(Messages.get("ClientUtils.queryTaskTimeout")) || + // Pooled connection network errors + e.message.includes("connect ETIMEDOUT") ); } } diff --git a/mysql/lib/mysql_pool_client.ts b/mysql/lib/mysql_pool_client.ts index 298c5294..a89ba990 100644 --- a/mysql/lib/mysql_pool_client.ts +++ b/mysql/lib/mysql_pool_client.ts @@ -14,8 +14,7 @@ limitations under the License. */ -import { ClientWrapper } from "../../common/lib/client_wrapper"; -import { createPool, PoolOptions, Pool } from "mysql2/promise"; +import { createPool, PoolOptions } from "mysql2/promise"; import { AwsPoolClient } from "../../common/lib/aws_pool_client"; import { Messages } from "../../common/lib/utils/messages"; import { AwsWrapperError } from "../../common/lib/utils/errors"; @@ -47,7 +46,7 @@ export class AwsMysqlPoolClient implements AwsPoolClient { return this.targetPool.pool._allConnections.length; } - async releaseResources() { + async releaseResources(): Promise { await this.targetPool.end(); } } diff --git a/pg/lib/dialect/pg_database_dialect.ts b/pg/lib/dialect/pg_database_dialect.ts index 82b79ae6..753c59f2 100644 --- a/pg/lib/dialect/pg_database_dialect.ts +++ b/pg/lib/dialect/pg_database_dialect.ts @@ -176,12 +176,11 @@ export class PgDatabaseDialect implements DatabaseDialect { finalPoolConfig.max = poolConfig?.maxConnections; finalPoolConfig.min = poolConfig?.minConnections; finalPoolConfig.idleTimeoutMillis = poolConfig?.idleTimeoutMillis; - finalPoolConfig.connectionTimeoutMillis = poolConfig?.connectionTimeoutMillis; finalPoolConfig.allowExitOnIdle = poolConfig?.allowExitOnIdle; return finalPoolConfig; } - end(clientWrapper: ClientWrapper): Promise { - return clientWrapper.client.end(); + async end(clientWrapper: ClientWrapper): Promise { + return await clientWrapper.client.end(); } } diff --git a/pg/lib/pg_error_handler.ts b/pg/lib/pg_error_handler.ts index 94f13764..749bf638 100644 --- a/pg/lib/pg_error_handler.ts +++ b/pg/lib/pg_error_handler.ts @@ -26,7 +26,8 @@ export class PgErrorHandler implements ErrorHandler { return ( e.message.includes("Connection terminated unexpectedly") || e.message.includes("Client has encountered a connection error and is not queryable") || - e.message.includes("Query read timeout") + e.message.includes("Query read timeout") || + e.message.includes("Connection terminated due to connection timeout") ); } } diff --git a/pg/lib/pg_pool_client.ts b/pg/lib/pg_pool_client.ts index 4947070f..c8e8bb0c 100644 --- a/pg/lib/pg_pool_client.ts +++ b/pg/lib/pg_pool_client.ts @@ -14,7 +14,6 @@ limitations under the License. */ -import { ClientWrapper } from "../../common/lib/client_wrapper"; import { Pool, PoolClient, PoolConfig } from "pg"; import { AwsPoolClient } from "../../common/lib/aws_pool_client"; import { Messages } from "../../common/lib/utils/messages"; @@ -41,10 +40,7 @@ export class AwsPgPoolClient implements AwsPoolClient { } async end(poolClient: any) { - if (poolClient == undefined) { - return; - } - await poolClient.release(true); + await poolClient?.release(true); } getIdleCount(): number { @@ -55,7 +51,7 @@ export class AwsPgPoolClient implements AwsPoolClient { return this.targetPool.totalCount; } - async releaseResources() { + async releaseResources(): Promise { await this.targetPool.end(); } } diff --git a/tests/integration/container/tests/read_write_splitting.test.ts b/tests/integration/container/tests/read_write_splitting.test.ts index ef060772..0927ba4c 100644 --- a/tests/integration/container/tests/read_write_splitting.test.ts +++ b/tests/integration/container/tests/read_write_splitting.test.ts @@ -38,7 +38,7 @@ let initClientFunc: (props: any) => any; let client: any; let secondaryClient: any; let auroraTestUtility: AuroraTestUtility; -let provider: any; +let provider: InternalPooledConnectionProvider | null; async function initDefaultConfig(host: string, port: number, connectToProxy: boolean): Promise { let config: any = { @@ -100,7 +100,6 @@ describe("aurora read write splitting", () => { if (client !== null) { try { await client.end(); - await client.releaseResources(); } catch (error) { // pass } @@ -524,9 +523,7 @@ describe("aurora read write splitting", () => { client = initClientFunc(config); secondaryClient = initClientFunc(config); - const provider = new InternalPooledConnectionProvider( - new AwsPoolConfig({ minConnections: 0, maxConnections: 10, maxIdleConnections: 10, connectionTimeoutMillis: 10000 }) - ); + const provider = new InternalPooledConnectionProvider(new AwsPoolConfig({ minConnections: 0, maxConnections: 10, maxIdleConnections: 10 })); ConnectionProviderManager.setConnectionProvider(provider); @@ -567,7 +564,11 @@ describe("aurora read write splitting", () => { logger.debug(error.stack); }); - provider = new InternalPooledConnectionProvider(); + provider = new InternalPooledConnectionProvider({ + minConnections: 0, + maxConnections: 10, + maxIdleConnections: 10 + }); ConnectionProviderManager.setConnectionProvider(provider); await client.connect(); diff --git a/tests/unit/internal_pool_connection_provider.test.ts b/tests/unit/internal_pool_connection_provider.test.ts index 203ca4e3..031994e2 100644 --- a/tests/unit/internal_pool_connection_provider.test.ts +++ b/tests/unit/internal_pool_connection_provider.test.ts @@ -110,8 +110,7 @@ describe("reader write splitting test", () => { when(mockDialect.getAwsPoolClient(anything())).thenReturn(mockAwsPoolClient); const config = { maxConnection: 10, - idleTimeoutMillis: 10000, - connectionTimeoutMillis: 10000 + idleTimeoutMillis: 60000 }; when(mockDialect.preparePoolClientProperties(anything(), anything())).thenReturn(config); const poolConfig: AwsPoolConfig = new AwsPoolConfig(config); @@ -149,8 +148,7 @@ describe("reader write splitting test", () => { when(mockDialect.getAwsPoolClient(anything())).thenReturn(mockAwsPoolClient); const config = { maxConnection: 10, - idleTimeoutMillis: 10000, - connectionTimeoutMillis: 10000 + idleTimeoutMillis: 60000 }; const myKeyFunc: InternalPoolMapping = { getKey: (hostInfo: HostInfo, props: Map) => {