Skip to content

Commit f760e89

Browse files
authored
Merge pull request #847 from constructive-io/devin/1773774783-fix-dropdb-terminate-backends
fix: terminate backends before dropping databases and close pg-cache pools in codegen
2 parents ed5a497 + 2604533 commit f760e89

3 files changed

Lines changed: 26 additions & 3 deletions

File tree

graphql/codegen/src/core/generate.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import path from 'node:path';
1010
import { buildClientSchema, printSchema } from 'graphql';
1111

1212
import { PgpmPackage } from '@pgpmjs/core';
13+
import { pgCache } from 'pg-cache';
1314
import { createEphemeralDb, type EphemeralDbResult } from 'pgsql-client';
1415
import { deployPgpm } from 'pgsql-seed';
1516

@@ -840,6 +841,10 @@ export async function generateMulti(
840841
} finally {
841842
for (const shared of sharedSources.values()) {
842843
const keepDb = Object.values(configs).some((c) => c.db?.keepDb);
844+
// Release pg-cache pool for this ephemeral database before dropping
845+
// deployPgpm() caches connections that must be closed first
846+
pgCache.delete(shared.ephemeralDb.config.database);
847+
await pgCache.waitForDisposals();
843848
shared.ephemeralDb.teardown({ keepDb });
844849
}
845850
}

graphql/codegen/src/core/introspect/source/pgpm-module.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
import { PgpmPackage } from '@pgpmjs/core';
1111
import { buildSchema, introspectionFromSchema } from 'graphql';
12-
import { getPgPool } from 'pg-cache';
12+
import { getPgPool, pgCache } from 'pg-cache';
1313
import { createEphemeralDb, type EphemeralDbResult } from 'pgsql-client';
1414
import { deployPgpm } from 'pgsql-seed';
1515

@@ -251,6 +251,11 @@ export class PgpmModuleSchemaSource implements SchemaSource {
251251

252252
return { introspection };
253253
} finally {
254+
// Release pg-cache pool for this ephemeral database before dropping
255+
// deployPgpm() and getPgPool() cache connections that must be closed first
256+
pgCache.delete(dbConfig.database);
257+
await pgCache.waitForDisposals();
258+
254259
// Clean up the ephemeral database
255260
teardown({ keepDb });
256261

postgres/pgsql-client/src/admin.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,22 @@ export class DbAdmin {
5858
try {
5959
this.run(`dropdb "${name}"`);
6060
} catch (err: any) {
61-
if (!err.message.includes('does not exist')) {
62-
log.warn(`Could not drop database ${name}: ${err.message}`);
61+
if (err.message.includes('does not exist')) {
62+
return;
6363
}
64+
if (err.message.includes('is being accessed by other users')) {
65+
log.warn(`Database ${name} has active sessions, terminating backends and retrying drop...`);
66+
try {
67+
this.run(
68+
`psql -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '${name}' AND pid <> pg_backend_pid();"`
69+
);
70+
this.run(`dropdb "${name}"`);
71+
} catch (retryErr: any) {
72+
log.warn(`Could not drop database ${name} after terminating backends: ${retryErr.message}`);
73+
}
74+
return;
75+
}
76+
log.warn(`Could not drop database ${name}: ${err.message}`);
6477
}
6578
}
6679

0 commit comments

Comments
 (0)