Skip to content

Commit 23e249d

Browse files
committed
fix: fail Redis commands fast instead of hanging the request
With REQUIRE_API_KEY turned off, /price stopped answering at all — no status, no error, just a timeout. /status kept working, which made it look like the key change had half-applied. ioredis queues commands while disconnected by default, so against a host that no longer resolves every call sits in the offline queue waiting for a connection that never arrives. The await never settles. That is a hang rather than a rejection, so the try/catch around getCachedPrice cannot see it and the fallback to Postgres it exists to trigger never runs. Nothing new broke here. The hang has been present for as long as Redis has been gone; the 401 was hiding it, because the auth hook rejected every request before a handler could reach Redis. Opening the API up removed the thing that was accidentally protecting it. enableOfflineQueue: false makes those commands reject immediately, which is what every caller already assumes: cached reads fall back to the database, cache writes are best-effort, and x402 metering fails closed on a request it cannot meter. Worth noting the shape of this one — a dead dependency that produced no errors, no logs and no failed requests, only silence, and became visible solely because an unrelated setting stopped masking it. Claude-Session: https://claude.ai/code/session_01USgemLt4Rnz4SGB1Srf3GB
1 parent b146b21 commit 23e249d

1 file changed

Lines changed: 15 additions & 0 deletions

File tree

src/redis.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ import { config, activeNetwork } from './config'
44
export const redis = new Redis(config.redis.url, {
55
maxRetriesPerRequest: 3,
66
lazyConnect: true,
7+
// Fail commands immediately while disconnected instead of queueing them.
8+
//
9+
// ioredis defaults this to true, so with an unreachable host every command
10+
// sits in the offline queue waiting for a connection that never comes. The
11+
// await simply never resolves — a hang, not an error, so the try/catch in
12+
// getCachedPrice cannot help and the request dies of timeout instead of
13+
// falling through to Postgres.
14+
//
15+
// It stayed hidden while REQUIRE_API_KEY was on, because the auth hook
16+
// rejected requests before any handler could reach Redis. Opening the API up
17+
// turned a 401 into a hang, which looked like the key change had failed.
18+
//
19+
// Rejecting fast is what the callers already expect: reads fall back to the
20+
// database, writes are best-effort, and x402 metering fails closed.
21+
enableOfflineQueue: false,
722
// ioredis retries about once a second forever by default. Against a host
823
// that no longer resolves that is a DNS lookup and two log lines every
924
// second — roughly 170k lines a day, which buries every real message in the

0 commit comments

Comments
 (0)