Compare commits

7 Commits
Author SHA1 Message Date
Gabriel20xxandGitHub e2592508cb Merge pull request #2 from gabriel20xx/copilot/fix-startup-issue-retry-db-connection
Add retry mechanism for database connection on startup
2026-05-19 13:23:36 +02:00
09ae5309d4 Clamp and validate DB_CONNECT_RETRIES and DB_CONNECT_RETRY_DELAY_MS env vars
Agent-Logs-Url: https://github.com/gabriel20xx/CollabTable/sessions/3d38d5f2-ce12-45a3-bcfe-9fb96f3581ce

Co-authored-by: gabriel20xx <21219769+gabriel20xx@users.noreply.github.com>
2026-05-19 11:23:06 +00:00
Gabriel20xxandGitHub dbab7b1934 Merge pull request #3 from gabriel20xx/copilot/create-github-workflow-file
Add GitHub Actions workflow to build and publish Docker image to Docker Hub
2026-05-19 13:22:40 +02:00
a896ae8209 Skip Docker Hub login step on pull_request events
Agent-Logs-Url: https://github.com/gabriel20xx/CollabTable/sessions/aef8ec67-fa60-4789-b968-81db2b5c793c

Co-authored-by: gabriel20xx <21219769+gabriel20xx@users.noreply.github.com>
2026-05-19 11:22:16 +00:00
94382573d0 Add Docker build and publish GitHub Actions workflow
Agent-Logs-Url: https://github.com/gabriel20xx/CollabTable/sessions/e8ce937b-f84e-41c0-a60a-155c2f512a61

Co-authored-by: gabriel20xx <21219769+gabriel20xx@users.noreply.github.com>
2026-05-19 11:16:36 +00:00
76c4a5ef96 Use exponential backoff and tighten connection error detection
Agent-Logs-Url: https://github.com/gabriel20xx/CollabTable/sessions/2bd9068b-15e3-43bb-81b9-94b4fb93bfdc

Co-authored-by: gabriel20xx <21219769+gabriel20xx@users.noreply.github.com>
2026-05-19 11:16:09 +00:00
c82b8aebca Add retry mechanism for database connection on startup
Agent-Logs-Url: https://github.com/gabriel20xx/CollabTable/sessions/2bd9068b-15e3-43bb-81b9-94b4fb93bfdc

Co-authored-by: gabriel20xx <21219769+gabriel20xx@users.noreply.github.com>
2026-05-19 11:15:05 +00:00
3 changed files with 65 additions and 35 deletions
+37
View File
@@ -0,0 +1,37 @@
name: Build and Publish Docker Image
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: ./CollabTableServer
file: ./CollabTableServer/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: |
gabriel20xx/collabtable:latest
gabriel20xx/collabtable:${{ github.sha }}
+1 -34
View File
@@ -18,8 +18,7 @@
"eslint-config-prettier": "^9.1.0",
"express": "^4.18.2",
"pg": "^8.11.3",
"prettier": "^3.3.3",
"ws": "^8.16.0"
"prettier": "^3.3.3"
},
"devDependencies": {
"@types/better-sqlite3": "^7.6.11",
@@ -27,7 +26,6 @@
"@types/express": "^4.17.21",
"@types/node": "^20.10.6",
"@types/pg": "^8.10.2",
"@types/ws": "^8.5.10",
"ts-node-dev": "^2.0.0",
"typescript": "^5.3.3"
}
@@ -452,16 +450,6 @@
"dev": true,
"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": {
"version": "7.18.0",
"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==",
"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": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+26
View File
@@ -296,7 +296,33 @@ export const dbAdapter: DBAdapter = clientType === 'postgres' || clientType ===
: new SqliteAdapter();
export async function initializeDatabase() {
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 };