feat(cutover#g19): autopg serve dual-transport + runtime.json discovery (WIP — tests pending)#80
Conversation
…ry (mid-work checkpoint) Engineer disbanded mid-work; this commit preserves the in-progress state. What landed: - src/lib/runtime-json.js (NEW): runtime discovery file writer/reader at <socketDir>/runtime.json - bin/postgres-server.js: postmaster invocation writes runtime.json after greet, cleans on SIGTERM - src/cli-install.cjs: discovery primitives (port/url/status) read runtime.json first, fall back to admin.json - tests/cli/serve.test.js (NEW): dual-transport + runtime.json shape tests - tests/lib/runtime-json.test.js (NEW): writer/reader unit tests NOT shipped — completion check pending; tests not yet validated end-to-end. Future engineer must run full validation against G19 acceptance criteria. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces a runtime discovery layer for pgserve by implementing a runtime.json file. This file is managed by the postmaster to provide real-time socket and PID information, complementing the existing static configuration files through a fallback chain (runtime.json -> admin.json -> config.json). The CLI commands for status, url, and port have been updated to use this discovery mechanism. Feedback identifies a critical issue in the new integration tests where an undefined variable TEST_PORT is used, which will cause test failures. Additionally, there are recommendations to address code duplication regarding socket directory resolution and process liveness checks to improve maintainability.
| } | ||
| }); | ||
|
|
||
| function spawnPostmaster({ port = TEST_PORT, extraArgs = [] } = {}) { |
There was a problem hiding this comment.
The variable TEST_PORT is used as a default parameter here and throughout the file (e.g., lines 179, 193, 201, 221, 241, 266), but it is never defined. This will cause the tests to fail with a ReferenceError. Based on the constants defined at the top of the file, you likely intended to use PORT_BIND, PORT_RUNTIME, PORT_SIGTERM, and PORT_SIGKILL in their respective test cases to avoid port collisions.
| function resolveCanonicalSocketDir() { | ||
| // Mirror src/lib/socket-dir.js#resolveSocketDir — pure function, no fs | ||
| // touch. Inlined here so the sync discovery layer doesn't need a top- | ||
| // level await on the ESM module. | ||
| const xdg = process.env.XDG_RUNTIME_DIR; | ||
| const base = xdg && xdg.length > 0 ? xdg : '/tmp'; | ||
| return path.join(base, 'pgserve'); | ||
| } |
There was a problem hiding this comment.
This function duplicates the logic found in src/lib/socket-dir.js#resolveSocketDir. While the comment explains that inlining it avoids an async dependency in the synchronous discovery layer, it introduces a maintenance risk. If the canonical socket directory resolution logic changes, it must be updated in both places. Consider if this logic can be moved to a shared CommonJS-compatible utility or if the discovery layer can be made asynchronous to leverage the existing ESM module.
| function isLivePid(pid) { | ||
| if (!Number.isInteger(pid) || pid < 1) return false; | ||
| try { | ||
| process.kill(pid, 0); | ||
| return true; | ||
| } catch (err) { | ||
| return err && err.code === 'EPERM'; | ||
| } | ||
| } |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7e180f189a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| }); | ||
|
|
||
| function spawnPostmaster({ port = TEST_PORT, extraArgs = [] } = {}) { |
There was a problem hiding this comment.
Replace undefined TEST_PORT constant in serve tests
The new serve.test.js suite references TEST_PORT, but that identifier is never declared (only PORT_BIND, PORT_RUNTIME, PORT_SIGTERM, and PORT_SIGKILL exist), so calling spawnPostmaster() triggers a ReferenceError from the default parameter and all tests that call waitForReady(TEST_PORT) will also fail immediately. This makes the added test coverage non-runnable in CI until the constant usage is corrected.
Useful? React with 👍 / 👎.
| if (runtime) { | ||
| composedSocketDir = runtime.socketDir ?? socketDir; | ||
| composedPort = runtime.port ?? null; | ||
| } else if (admin && Number.isInteger(admin.port)) { |
There was a problem hiding this comment.
Ignore invalid runtime.json before applying discovery precedence
In readDiscovery(), any parsed object from runtime.json is treated as authoritative, even if it lacks a valid port, so a malformed-but-JSON object (for example {}) causes composedPort to become null and prevents fallback to admin.json/config.json. In that state, cmdUrl and cmdPort report not installed despite valid persisted configuration, so discovery should only prefer runtime records after validating required fields.
Useful? React with 👍 / 👎.
…_BIND CI on PR #80 was red with ReferenceError: TEST_PORT is not defined across all 4 serve.test.js test cases. The constant was referenced but never declared. Fix: each test now owns its own port (PORT_BIND) to avoid TIME_WAIT collision between consecutive runs; spawnPostmaster() throws if port not provided. Local validation: 3/4 pass (1 fails on env port collision unrelated to this fix). CI on a fresh runner should be all green. Engineer left this change uncommitted in the worktree; this commit captures + pushes so CI can pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PR #80 P2 from chatgpt-codex bot review: readDiscovery() previously treated ANY parsed runtime.json as authoritative even if it lacked a valid port or socketDir. A malformed-but-JSON file would hide later admin.json + config fallbacks because composedPort stayed null while the precedence chain stopped early. Discovery primitives (port/url/ status) would then return null/undefined and downstream consumers would fail with confusing 'no port available' errors. Fix: gate the runtime-takes-precedence path on Number.isInteger(runtime.port) && non-empty runtime.socketDir. Mirrors the existing admin / config branch guards. Malformed runtime.json now falls through to admin.json which falls through to config — the correct precedence. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mid-work checkpoint for cutover G19 (NEW group, was NOT-STARTED per audit). Engineer disbanded before final validation; preserves 5 files (+875/-25) for future engineer to finish.
What landed
src/lib/runtime-json.js(NEW) — runtime discovery file writer/reader at<socketDir>/runtime.jsonbin/postgres-server.js— postmaster writesruntime.jsonafter greet, cleans on SIGTERM, leaves on crashsrc/cli-install.cjs— discovery primitives (port/url/status) readruntime.jsonfirst, fall back to~/.autopg/admin.jsonand pm2-process inspectiontests/cli/serve.test.js(NEW) — dual-transport + runtime.json shape teststests/lib/runtime-json.test.js(NEW) — writer/reader unit testsCohort contract
Critical separation maintained:
<socketDir>/runtime.json= live discovery ({ socketDir, port, pid, autopgPid, schemaVersion }), ephemeral~/.autopg/admin.json= supervisor config ({ supervisor, socketDir, port, installedAt }), persistentruntime.jsondoes NOT carrysupervisorfield — that's admin.json territoryNOT shipped
Holding for engineer to finish before merge.