ConnectionTimeoutError: Connection timeout
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 17.6k
- Forks
- 2k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 40
Description
I am using this module to cache queries on a nextjs/node application.
Within nextjs I have a simple file within the /api folder (/api/cache/client.js) that contains the following code:
const redis = require("redis");
const REDIS_CLIENT_URI = process.env.REDIS_URL || "redis://127.0.0.1:6379";
let client = null;
const onRedisError = (err) => {
console.error(err);
};
const onRedisConnect = () => {
console.log("Redis connected");
};
const onRedisReconnecting = () => {
console.log("Redis reconnecting");
};
const onRedisReady = () => {
console.log("Redis ready!");
};
async function redisClient() {
try {
if (client === null) {
client = redis.createClient({
url: REDIS_CLIENT_URI,
});
await client.connect();
}
client.on("error", onRedisError);
client.on("connect", onRedisConnect);
client.on("reconnecting", onRedisReconnecting);
client.on("ready", onRedisReady);
return client;
} catch (e) {
console.log("not connected");
console.log(e.message);
return null;
}
}
async function redisGet(key, func) {
try {
const client = await redisClient();
if (client === null) {
throw new Error("Redis is not connected");
}
const data = await client.get(key);
if (data === null) {
console.log("miss");
const query = await func();
await redisSet(key, JSON.stringify(query));
return query;
} else {
console.log("hit");
return JSON.parse(data);
}
} catch (e) {
console.log(e.message);
return await func();
}
}
async function redisSet(key, data) {
try {
const client = await redisClient();
if (client === null) {
throw new Error("Redis is not connected");
}
await client.set(key, data, { EX: 86400 * 31 });
} catch (e) {
console.log(e.message);
}
}
module.exports.redisGet = redisGet;
I then require this file in any /api files where I need to use redis to cache the results of any asycnhronous function that makes a call to an external API e.g.
const { redisGet } = require("../cache/client");
export default async function handler(req, res) {
try {
const data = JSON.parse(req.body);
const query = await redisGet(
`${data.customer_id}:${data.fromDate}/${data.toDate}`,
async () => {
try {
const res = await fetch(
`https://jsonplaceholder.typicode.com/comments`
);
const data = await res.json();
return data;
} catch (e) {
console.log(e);
throw e;
}
}
);
console.log(query);
res.status(200).send({ query });
} catch (e) {
console.log(e);
console.log(e.message);
res.status(500).json(e.message);
}
}
}
This works fine because I am able to get the commands in my output such as hit and miss whenever I call any of the API endpoints where I am using redisGet, however, my server also seems to constantly be giving me a connection timeout error followed by Redis reconnecting:
at TLSSocket.<anonymous> (/Users/kamrankhan/Sites/2020/visifii/visifii/node_modules/@node-redis/client/dist/lib/client/socket.js:169:124)
at Object.onceWrapper (node:events:509:28)
at TLSSocket.emit (node:events:390:28)
at TLSSocket.emit (node:domain:475:12)
at TLSSocket.Socket._onTimeout (node:net:486:8)
at listOnTimeout (node:internal/timers:557:17)
at processTimers (node:internal/timers:500:7)
Redis reconnecting
I don't know what I'm doing wrong here. I have also set the timeout config time to 10000 and also set the maxmemory-policy config to allkeys-lru. Can anyone nudge me in the right direction? Am I missing something? Any help would be appreciated!
Environment:
- Node.js Version:
- v16.10.0
- Redis Server Version:
- Redis server v=6.2.6 sha=00000000:0 malloc=libc bits=64 build=c6f3693d1aced7d9
- Node Redis Version:
- redis@4.0.4
- Platform:
- Mac OS Mojave 10.14.6
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with /api/cache/client.js, especially redis.createClient({ url }) and client.connect(), then compare the connection behavior with the timeout stack trace in node_modules/@node-redis/client/dist/lib/client/socket.js. Reproduce the API request and determine why the Redis connection times out; done means the cache still reports hits or misses without repeated timeout and reconnect messages.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, next.js, node.js, redis
- Domain
- api, backend, database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100