Repository navigation
v0.149.0
Redis: the shared client reconnects after an outage, and RedisRateLimiter has a timeout (#982)
Behaviour change. Nothing to migrate. See Middleware → Rate limiting and Facades → Redis.
- Before, once Bun's Redis client gave up on a connection (a connect timeout, or
maxRetriesreconnects), it never connected again andRedisManagerkept handing it out. Every Redis command then failed until the process restarted, andRedisRateLimiterwithfailOpen(the default) turned every limit off. RedisManager.clientnow replaces a client that is down: it closes it and builds a new one. Down means not connected, and not still making the first connection the manager started for it (building a client now starts connecting it; a connect pending pastconnectionTimeout+ 5 s counts as failed). It waits 0.5 s first, so a blip Bun's own reconnect covers costs nothing; the wait doubles to 10 s with each new client that fails to connect and resets once one connects. This covers everything on the shared connection: theRedisfacade,RedisRateLimiter, the"redis"cache store,RedisNonceStore,RedisReceiptStore. A client you pass to one of them yourself (new RedisRateLimiter({ client })) is not covered.- Read
Redis.client(orRedisManager.client) each time instead of keeping it: a kept reference may be a client that was replaced and closed. Callingconnect()again on Bun's failed client is not a fix: on some Bun versions (1.3.x on Linux) it never settles. RedisRateLimitertakestimeout(ms, default250,0turns it off). A call that runs past it followsfailOpen/failClosedat once and reports aRedisRateLimiterTimeoutError(new export ofgemi/services) toonError. Before, a limited request could wait 10 to 30 s during an outage, and with no limit when Redis stopped answering on an open connection. Redis may still run a script that timed out, so that call can still be counted. Raisetimeoutif your Redis is far from the app (a cross-region round trip near 250 ms would fail open or closed on every call).