fix(cli): stop info command from hanging when database is unreachable - #740
Priyanshubhartistm wants to merge 5 commits into
Conversation
Signed-off-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
🦋 Changeset detectedLatest commit: 1c686c7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
chappie-daemon
left a comment
There was a problem hiding this comment.
Reviewed against a live reproduction of the reported hang. The fix works, and the diagnosis holds up under measurement.
Measured
Unreachable database (postgres://…@10.255.255.1:5432/…), each run wrapped in timeout 20:
| tree | command | result |
|---|---|---|
base main |
nostream info |
exit 124 at 20 s — hung, no output at all |
| this PR (a2e615b) | nostream info |
exit 0 in 3.7 s, reporting Events: unavailable / Uptime: unavailable |
base main |
invite create --uses 1 --expires-in 3600 |
exit 124 at 20 s — hung, no output |
The root-cause paragraph is correct
I checked the obvious alternative before believing it. src/cli/commands/invite.ts already sets propagateCreateError: true with an explicit acquire timeout and classifies unreachable-database errors, so the cheapest hypothesis was that info.ts simply has its pool configured wrong.
It is not. Base main with propagateCreateError: false flipped to true — one word, nothing else changed — still exits 124 at 20 s. The acquire timeout fires and the process stays alive regardless, which is what a leaked socket looks like and what the comment in this change describes. The swap to pg.Client is warranted.
connectionTimeoutMillis: 1000 is doing real work here, by the way: without it pg.Client.connect() waits indefinitely on an unroutable host, so the client swap alone would not have been enough. It is good that it is in both branches of the config, and 1000 ms sits consistently beside the other timeouts in this file.
The same hang is not specific to info
invite create against the same unreachable database hangs identically — exit 124 at 20 s, no output — because it builds its own knex pool in the same shape. If the intent is "the CLI fails cleanly when the database is unreachable", that command needs the same treatment; if the scope is deliberately info-only, a sentence in the PR body saying so would help a future reader. The helper introduced here looks like a good candidate to share between the two commands.
Missing regression test
This is a class a test catches cheaply and permanently: spawn the CLI with an unreachable DB_URI under a short deadline and assert that it exits — and, for --json, that the event count is reported as unavailable rather than the process being killed. The suite does not need a database for that, so the test fits the existing shape.
Smaller notes, none blocking
pg@8.9.0is already a direct dependency, so the new import adds nothing to the dependency surface.- Two hunks are unrelated formatting churn — the multi-line
docker inspectcall and thenew Set((…))parenthesis cleanup. Fine if that is the formatter, but it widens the diff beyond the fix. - The branch is behind
main(merge-baseis not an ancestor), so it will need an update before merge.
Nothing here questions the change itself: it is small, correct, and the comment explaining why a raw client is used is worth keeping. Good fix — I would just like to see it reach invite too.
Signed-off-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
Description
getEventCount()insrc/cli/commands/info.tsopened aknexconnection pool for a single ad-hoc query. When the initial connection attempt itself failed or timed out, the pool'sdestroy()resolved without actually closing the underlying socket, leaving an open handle behind and keeping the Node process alive indefinitely.Replaces the
knexpool with a rawpg.Client(connect()/query()/end()), which reliably closes its socket even when the connection attempt itself fails.Related Issue
Closes #739.
Motivation and Context
nostream info(andnostream info --json) would hang forever with no error or timeout if the configured database was unreachable, instead of failing cleanly like every other CLI command.