-
Notifications
You must be signed in to change notification settings - Fork 1
⚡ Bolt: optimize UAT repository initialization #22297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,6 +3,11 @@ import baseLogger from '../../config/logger.js'; | |||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| const logger = baseLogger.child({ name: 'uat-repo' }); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| // BOLT OPTIMIZATION: Guard initialization to prevent redundant schema checks on every operation. | ||||||||||||||||||||||||||||||||||||||||||||||||
| // This reduces database round-trips for high-frequency UAT event logging. | ||||||||||||||||||||||||||||||||||||||||||||||||
| // Pattern also used in high-throughput tickets repository. | ||||||||||||||||||||||||||||||||||||||||||||||||
| let initializationPromise: Promise<void> | null = null; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| export type UATCheckpoint = { | ||||||||||||||||||||||||||||||||||||||||||||||||
| run_id: string; | ||||||||||||||||||||||||||||||||||||||||||||||||
| checkpoint: string; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -13,26 +18,33 @@ export type UATCheckpoint = { | |||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| async function ensureTable() { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const pool = getPostgresPool(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||
| await pool.query(` | ||||||||||||||||||||||||||||||||||||||||||||||||
| CREATE TABLE IF NOT EXISTS maestro_uat_checkpoints ( | ||||||||||||||||||||||||||||||||||||||||||||||||
| id SERIAL PRIMARY KEY, | ||||||||||||||||||||||||||||||||||||||||||||||||
| run_id TEXT NOT NULL, | ||||||||||||||||||||||||||||||||||||||||||||||||
| checkpoint TEXT NOT NULL, | ||||||||||||||||||||||||||||||||||||||||||||||||
| verdict TEXT NOT NULL, | ||||||||||||||||||||||||||||||||||||||||||||||||
| evidence_uris JSONB, | ||||||||||||||||||||||||||||||||||||||||||||||||
| actor TEXT, | ||||||||||||||||||||||||||||||||||||||||||||||||
| created_at TIMESTAMPTZ DEFAULT NOW() | ||||||||||||||||||||||||||||||||||||||||||||||||
| if (initializationPromise) return initializationPromise; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| initializationPromise = (async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||
| const pool = getPostgresPool(); | ||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+23
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If Proposed fix initializationPromise = (async () => {
- const pool = getPostgresPool();
try {
+ const pool = getPostgresPool();
await pool.query(`📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||
| await pool.query(` | ||||||||||||||||||||||||||||||||||||||||||||||||
| CREATE TABLE IF NOT EXISTS maestro_uat_checkpoints ( | ||||||||||||||||||||||||||||||||||||||||||||||||
| id SERIAL PRIMARY KEY, | ||||||||||||||||||||||||||||||||||||||||||||||||
| run_id TEXT NOT NULL, | ||||||||||||||||||||||||||||||||||||||||||||||||
| checkpoint TEXT NOT NULL, | ||||||||||||||||||||||||||||||||||||||||||||||||
| verdict TEXT NOT NULL, | ||||||||||||||||||||||||||||||||||||||||||||||||
| evidence_uris JSONB, | ||||||||||||||||||||||||||||||||||||||||||||||||
| actor TEXT, | ||||||||||||||||||||||||||||||||||||||||||||||||
| created_at TIMESTAMPTZ DEFAULT NOW() | ||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_uat_run ON maestro_uat_checkpoints(run_id); | ||||||||||||||||||||||||||||||||||||||||||||||||
| `); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e: any) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| logger.warn( | ||||||||||||||||||||||||||||||||||||||||||||||||
| { err: e }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| 'ensureTable maestro_uat_checkpoints failed (mock mode?)', | ||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_uat_run ON maestro_uat_checkpoints(run_id); | ||||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e: any) { | ||||||||||||||||||||||||||||||||||||||||||||||||
| logger.warn( | ||||||||||||||||||||||||||||||||||||||||||||||||
| { err: e }, | ||||||||||||||||||||||||||||||||||||||||||||||||
| 'ensureTable maestro_uat_checkpoints failed (mock mode?)', | ||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
| initializationPromise = null; | ||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Check how tickets.ts handles initialization errors to confirm if swallowing is intentional
# Find tickets.ts and examine its ensureTable or similar initialization pattern
fd -t f 'tickets.ts' --exec cat {} \; | rg -A 20 -B 5 'initializationPromise|ensureTable'Repository: BrianCLong/summit Length of output: 5487 🏁 Script executed: cd server/src/db/repositories && cat -n uat.ts | head -50Repository: BrianCLong/summit Length of output: 1873 Re-throw the error to match the pattern in The catch block logs the error and clears The codebase already uses the correct pattern in Re-throw to propagate initialization failure } catch (e: any) {
logger.warn(
{ err: e },
'ensureTable maestro_uat_checkpoints failed (mock mode?)',
);
initializationPromise = null;
+ throw e;
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||
| })(); | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| return initializationPromise; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+43
to
+47
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current implementation of Additionally, since the error is caught and swallowed, the promise resolves successfully. This means callers awaiting } catch (e: any) {
logger.warn(
{ err: e },
'ensureTable maestro_uat_checkpoints failed (mock mode?)',
);
initializationPromise = null;
}
})();
return initializationPromise!; |
||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| export async function addUATCheckpoint(c: UATCheckpoint) { | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If
getPostgresPool()throws during the first call (for example during transient DB startup/config failures), that rejection is captured ininitializationPromiseand never cleared, so every laterensureTable()call reuses the same rejected promise and the repository cannot recover without a process restart. Before this change, each call retried pool acquisition; with this guard, recovery is blocked unless the promise is reset on pool-init failure.Useful? React with 👍 / 👎.