redis / redis/node-redis

ConnectionTimeoutError: Connection timeout

Open
#2,045 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.