1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-11-24 20:06:55 +01:00

Validate also that if query halts readiness fails

This commit is contained in:
Gastón Fournier 2025-10-23 16:49:15 +02:00
parent e4c322d633
commit 887d154cfe
No known key found for this signature in database
GPG Key ID: AF45428626E17A8E
3 changed files with 55 additions and 3 deletions

View File

@ -81,9 +81,22 @@ export class ReadyCheckController extends Controller {
} }
try { try {
connection.query({ await connection.query('BEGIN');
text: 'SELECT 1', await connection.query({
text: `SET LOCAL statement_timeout = ${timeoutMs}`,
}); });
await connection.query('SELECT 1');
await connection.query('COMMIT');
} catch (error) {
try {
await connection.query('ROLLBACK');
} catch (rollbackError) {
this.logger.debug(
'Failed to rollback readiness timeout transaction',
rollbackError,
);
}
throw error;
} finally { } finally {
if (connection) { if (connection) {
await client.releaseConnection(connection); await client.releaseConnection(connection);

View File

@ -302,6 +302,5 @@ export interface IUnleashConfig {
userInactivityThresholdInDays: number; userInactivityThresholdInDays: number;
buildDate?: string; buildDate?: string;
unleashFrontendToken?: string; unleashFrontendToken?: string;
/** If true, the readiness endpoint will attempt a simple Postgres query to verify DB availability */
checkDbOnReady?: boolean; checkDbOnReady?: boolean;
} }

View File

@ -29,6 +29,46 @@ describe('DB is up', () => {
); );
await request.get('/ready').expect(200).expect('{"health":"GOOD"}'); await request.get('/ready').expect(200).expect('{"health":"GOOD"}');
}); });
test('fails fast when readiness query hangs', async () => {
const { request } = await setupAppWithCustomConfig(
db.stores,
{ checkDbOnReady: true },
db.rawDatabase,
);
const pool = db.rawDatabase.client.pool;
const originalAcquire = pool.acquire.bind(pool);
pool.acquire = () => {
const pending = originalAcquire();
pending.promise = pending.promise.then((conn: any) => {
const originalQuery = conn.query;
conn.query = (queryConfig: any, ...args: any[]) => {
const isSelectOne =
queryConfig?.toUpperCase() === 'SELECT 1';
if (isSelectOne) {
return originalQuery.call(
conn,
'SELECT pg_sleep(1)',
...args,
);
}
return originalQuery.call(conn, queryConfig, ...args);
};
return conn;
});
return pending;
};
try {
await request.get('/ready').expect(503);
} finally {
pool.acquire = originalAcquire;
}
});
}); });
describe('DB is down', () => { describe('DB is down', () => {