fix(ops): 自愈 goosed 会话 PostgreSQL,防止 H5 卡在创建新对话
103 Colima goosed 依赖宿主机 postgresql@17;库停止时 /agent/start 会 pool timeout 约 60s。新增 ensure 脚本、接入监控与发布前检查,并补充拓扑文档。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -59,6 +59,16 @@ Portal must be released as a runtime artifact. Do not edit source directly on 10
|
|||||||
| Compose env | `/Users/john/Project/goosed-prod/.env` |
|
| Compose env | `/Users/john/Project/goosed-prod/.env` |
|
||||||
| Image pattern | `tkmind/goosed:prod-${GOOSED_TAG}` |
|
| Image pattern | `tkmind/goosed:prod-${GOOSED_TAG}` |
|
||||||
| Session store | PostgreSQL `memind_sessions` through `GOOSE_SESSION_DB_URL` |
|
| Session store | PostgreSQL `memind_sessions` through `GOOSE_SESSION_DB_URL` |
|
||||||
|
| Session PostgreSQL | **Host** `postgresql@17` on `127.0.0.1:5432` (`/opt/homebrew/var/postgresql@17`) |
|
||||||
|
|
||||||
|
**Critical:** Colima goosed reaches the session DB via `host.docker.internal:5432`. If host PostgreSQL is stopped, H5 `/agent/start` hangs ~60s then fails with `pool timed out`, and the UI stays on「正在创建新对话…」. Recovery:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh john@58.38.22.103 'bash /Users/john/Project/Memind/scripts/ensure-goose-session-postgres.sh'
|
||||||
|
ssh john@58.38.22.103 '/opt/homebrew/opt/postgresql@17/bin/pg_isready -h 127.0.0.1 -p 5432'
|
||||||
|
```
|
||||||
|
|
||||||
|
`cn.tkmind.goosed-monitor`(103)运行 `goosed-prod/scripts/monitor-goosed-containers.mjs`,本地 native goosed 监控用 `scripts/monitor-goosed-fds.mjs`;两者都会在巡检时调用 `ensure-goose-session-postgres.sh`。
|
||||||
|
|
||||||
Container layout:
|
Container layout:
|
||||||
|
|
||||||
|
|||||||
Executable
+28
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# 103 Colima goosed 通过 host.docker.internal:5432 访问本机 PostgreSQL。
|
||||||
|
# 该库停止时,/agent/start 会在约 60s 后返回 pool timeout,H5 会卡在「正在创建新对话…」。
|
||||||
|
export PATH="/opt/homebrew/bin:/opt/homebrew/opt/postgresql@17/bin:${PATH:-/usr/bin:/bin}"
|
||||||
|
|
||||||
|
PGDATA="${GOOSE_SESSION_PGDATA:-/opt/homebrew/var/postgresql@17}"
|
||||||
|
PG_LOG="${GOOSE_SESSION_PG_LOG:-${HOME}/Library/Logs/postgresql@17.log}"
|
||||||
|
PG_HOST="${GOOSE_SESSION_PG_HOST:-127.0.0.1}"
|
||||||
|
PG_PORT="${GOOSE_SESSION_PG_PORT:-5432}"
|
||||||
|
|
||||||
|
if pg_isready -h "${PG_HOST}" -p "${PG_PORT}" -q 2>/dev/null; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) goose session postgres not ready; starting (${PGDATA})"
|
||||||
|
mkdir -p "$(dirname "${PG_LOG}")"
|
||||||
|
pg_ctl -D "${PGDATA}" -l "${PG_LOG}" start 2>/dev/null || true
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
if pg_isready -h "${PG_HOST}" -p "${PG_PORT}" -q 2>/dev/null; then
|
||||||
|
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) goose session postgres ready"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) goose session postgres still down (${PG_HOST}:${PG_PORT})" >&2
|
||||||
|
exit 1
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import { execFileSync, spawnSync } from 'node:child_process';
|
import { execFileSync, spawnSync } from 'node:child_process';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
const ENSURE_GOOSE_SESSION_POSTGRES = path.join(__dirname, 'ensure-goose-session-postgres.sh');
|
||||||
|
|
||||||
const DRY_RUN = process.argv.includes('--dry-run');
|
const DRY_RUN = process.argv.includes('--dry-run');
|
||||||
const FD_WARN = Number(process.env.GOOSED_FD_WARN ?? 180);
|
const FD_WARN = Number(process.env.GOOSED_FD_WARN ?? 180);
|
||||||
@@ -122,5 +127,25 @@ function monitorGoosed() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensureGooseSessionPostgres() {
|
||||||
|
try {
|
||||||
|
const result = spawnSync('/bin/bash', [ENSURE_GOOSE_SESSION_POSTGRES], {
|
||||||
|
encoding: 'utf8',
|
||||||
|
stdio: ['ignore', 'pipe', 'pipe'],
|
||||||
|
});
|
||||||
|
const output = `${result.stdout ?? ''}${result.stderr ?? ''}`.trim();
|
||||||
|
if (output) console.log(output);
|
||||||
|
if (result.status !== 0) {
|
||||||
|
console.warn('goose session postgres ensure failed');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn(
|
||||||
|
'goose session postgres ensure skipped:',
|
||||||
|
err instanceof Error ? err.message : err,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureGooseSessionPostgres();
|
||||||
cleanupSandboxProcesses();
|
cleanupSandboxProcesses();
|
||||||
monitorGoosed();
|
monitorGoosed();
|
||||||
|
|||||||
@@ -201,6 +201,17 @@ set -euo pipefail
|
|||||||
|
|
||||||
missing=0
|
missing=0
|
||||||
|
|
||||||
|
pg_isready_bin="/opt/homebrew/opt/postgresql@17/bin/pg_isready"
|
||||||
|
if [[ -x "${pg_isready_bin}" ]]; then
|
||||||
|
if ! "${pg_isready_bin}" -h 127.0.0.1 -p 5432 -q 2>/dev/null; then
|
||||||
|
echo "goosed dependency check failed: host PostgreSQL (127.0.0.1:5432) is not accepting connections" >&2
|
||||||
|
echo "Run: bash /Users/john/Project/Memind/scripts/ensure-goose-session-postgres.sh" >&2
|
||||||
|
missing=1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "goosed dependency check warning: pg_isready not found; skipping PostgreSQL readiness check" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
docker_bin="/opt/homebrew/bin/docker"
|
docker_bin="/opt/homebrew/bin/docker"
|
||||||
if [[ -x "${docker_bin}" ]] && "${docker_bin}" ps --format '{{.Names}}' 2>/dev/null | grep -q '^goosed-prod-1$'; then
|
if [[ -x "${docker_bin}" ]] && "${docker_bin}" ps --format '{{.Names}}' 2>/dev/null | grep -q '^goosed-prod-1$'; then
|
||||||
for index in 1 2 3 4; do
|
for index in 1 2 3 4; do
|
||||||
|
|||||||
Reference in New Issue
Block a user