fix: ensure QueryRunner is released in workspace schema operations (#16649)

## Summary

Fixes a database connection leak in `WorkspaceDataSourceService` where
`QueryRunner.release()` was not being called when schema operations
failed.

## Problem

The `createWorkspaceDBSchema` and `deleteWorkspaceDBSchema` methods use
TypeORM's QueryRunner but didn't wrap the operations in
try-catch-finally blocks. When schema operations fail (e.g., permission
denied, schema conflicts), the `QueryRunner.release()` method was never
called.

**Impact:** Failed schema operations leak database connections, which
can exhaust the connection pool and cause the application to hang or
crash under load.

## Solution

Wrap both methods in try-finally blocks to ensure
`queryRunner.release()` is always called, regardless of whether the
operation succeeds or fails.

## Changes

- `createWorkspaceDBSchema`: Wrapped in try-finally to ensure connection
release
- `deleteWorkspaceDBSchema`: Wrapped in try-finally to ensure connection
release
This commit is contained in:
Félix Malfait
2025-12-18 08:26:07 +01:00
committed by GitHub
parent 75ae2b401b
commit 1e615f7102
@@ -37,14 +37,15 @@ export class WorkspaceDataSourceService {
*/
public async createWorkspaceDBSchema(workspaceId: string): Promise<string> {
const schemaName = getWorkspaceSchemaName(workspaceId);
const queryRunner = this.coreDataSource.createQueryRunner();
await queryRunner.createSchema(schemaName, true);
try {
await queryRunner.createSchema(schemaName, true);
await queryRunner.release();
return schemaName;
return schemaName;
} finally {
await queryRunner.release();
}
}
/**
@@ -56,12 +57,13 @@ export class WorkspaceDataSourceService {
*/
public async deleteWorkspaceDBSchema(workspaceId: string): Promise<void> {
const schemaName = getWorkspaceSchemaName(workspaceId);
const queryRunner = this.coreDataSource.createQueryRunner();
await queryRunner.dropSchema(schemaName, true, true);
await queryRunner.release();
try {
await queryRunner.dropSchema(schemaName, true, true);
} finally {
await queryRunner.release();
}
}
public async executeRawQuery(