Merge pull request #2 from gabriel20xx/copilot/fix-startup-issue-retry-db-connection
Add retry mechanism for database connection on startup
This commit is contained in:
Generated
+1
-34
@@ -18,8 +18,7 @@
|
|||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"pg": "^8.11.3",
|
"pg": "^8.11.3",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3"
|
||||||
"ws": "^8.16.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/better-sqlite3": "^7.6.11",
|
"@types/better-sqlite3": "^7.6.11",
|
||||||
@@ -27,7 +26,6 @@
|
|||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
"@types/node": "^20.10.6",
|
"@types/node": "^20.10.6",
|
||||||
"@types/pg": "^8.10.2",
|
"@types/pg": "^8.10.2",
|
||||||
"@types/ws": "^8.5.10",
|
|
||||||
"ts-node-dev": "^2.0.0",
|
"ts-node-dev": "^2.0.0",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
@@ -452,16 +450,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/ws": {
|
|
||||||
"version": "8.18.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
|
|
||||||
"integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "7.18.0",
|
"version": "7.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz",
|
||||||
@@ -3717,27 +3705,6 @@
|
|||||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/ws": {
|
|
||||||
"version": "8.18.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
|
||||||
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"bufferutil": "^4.0.1",
|
|
||||||
"utf-8-validate": ">=5.0.2"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"bufferutil": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"utf-8-validate": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/xtend": {
|
"node_modules/xtend": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||||
|
|||||||
@@ -296,7 +296,33 @@ export const dbAdapter: DBAdapter = clientType === 'postgres' || clientType ===
|
|||||||
: new SqliteAdapter();
|
: new SqliteAdapter();
|
||||||
|
|
||||||
export async function initializeDatabase() {
|
export async function initializeDatabase() {
|
||||||
await dbAdapter.initialize();
|
const parsedRetries = parseInt(process.env.DB_CONNECT_RETRIES || '10', 10);
|
||||||
|
const maxRetries = Number.isNaN(parsedRetries) || parsedRetries < 1 ? 10 : parsedRetries;
|
||||||
|
|
||||||
|
const parsedDelay = parseInt(process.env.DB_CONNECT_RETRY_DELAY_MS || '3000', 10);
|
||||||
|
const retryDelayMs = Number.isNaN(parsedDelay) || parsedDelay < 0 ? 3000 : parsedDelay;
|
||||||
|
|
||||||
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
||||||
|
try {
|
||||||
|
await dbAdapter.initialize();
|
||||||
|
return;
|
||||||
|
} catch (err: any) {
|
||||||
|
const isConnectionError =
|
||||||
|
err?.code === 'ECONNREFUSED' ||
|
||||||
|
err?.code === 'ENOTFOUND' ||
|
||||||
|
err?.code === 'ETIMEDOUT';
|
||||||
|
|
||||||
|
if (!isConnectionError || attempt === maxRetries) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
const delay = retryDelayMs * Math.pow(2, attempt - 1);
|
||||||
|
console.warn(
|
||||||
|
`Database connection attempt ${attempt}/${maxRetries} failed (${err.code || err.message}). Retrying in ${delay}ms...`
|
||||||
|
);
|
||||||
|
await new Promise(resolve => setTimeout(resolve, delay));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { DBAdapter };
|
export type { DBAdapter };
|
||||||
|
|||||||
Reference in New Issue
Block a user