skip to Main Content

I’m developing service using Nest JS,

I want to create redis client module, that has publish service, and cache service that will be used by another modules

So here is my code:

  1. Redis client module
import { CacheModule, Module } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import * as redisStore from "cache-manager-redis-store";
import { ClientsModule, Transport } from "@nestjs/microservices";
import { RedisCacheService } from "./redis-cache.service";
import { RedisPublishService } from "./redis-publish.service";

@Module({
    imports: [
        CacheModule.register({
            inject: [ConfigService],
            useFactory: async (configService: ConfigService) => ({
                store: redisStore,
                host: configService.get<string>("REDIS_HOST"),
                port: configService.get<string>("REDIS_PORT"),
                password: configService.get<string>("REDIS_PASSWORD"),
            }),
        }),
        ClientsModule.registerAsync([
            {
                name:"PUBLISH_SERVICE",
                useFactory: async (configService: ConfigService) => {
                    const url = `redis://${configService.get<string>(
                        "REDIS_HOST"
                    )}:${configService.get<string>("REDIS_PORT")}`;

                    return {
                        transport: Transport.REDIS,
                        options: {
                            url: url,
                            password: configService.get<string>("REDIS_PASSWORD"),
                        },
                    }
                },
                inject: [ConfigService],
            },
        ]),
    ],
    providers: [RedisCacheService, RedisPublishService],
    exports: [RedisCacheService, RedisPublishService],
})
export class RedisClientModule {}

2.Redis Cache Service

import { CACHE_MANAGER, Inject, Injectable } from "@nestjs/common";
import { Cache } from "cache-manager";

@Injectable()
export class RedisCacheService {
    constructor(@Inject(CACHE_MANAGER) private readonly cache: Cache) {}

    async get<T>(key: string): Promise<T | undefined>{
        console.log("getting data from redis with key: " + key)
        return this.cache.get(key);
    }

    async set<T>(key:string, value:T):Promise<T> {
        return this.cache.set(key, value);
    }

    del(key: string): Promise<any>{
        return this.cache.del(key);
    }


    async setTtl<T>(key: string, value: T, ttl: number): Promise<T>{
        return this.cache.set(key,value,ttl);
    }
}
  1. Redis publish service
import { Inject, Injectable } from "@nestjs/common";
import { ClientProxy } from "@nestjs/microservices";
import { Observable } from "rxjs";

@Injectable()
export class RedisPublishService {
    constructor(@Inject('PUBLISH_SERVICE') private client: ClientProxy) {}

    emit<TResult = any, TInput = any>(pattern: any, data: TInput): Observable<TResult>{
        return this.client.emit(pattern,data);
    }

    send<TResult = any, TInput = any>(pattern: any, data: TInput): Observable<TResult>{
        return this.client.send(pattern,data);
    }





}

And module that using it:

@Module({
  imports:[RedisClientModule],
  providers: [ExampleService],
  controllers: [ExampleController]
})
export class ExampleModule {}

The service class:

@Injectable()
export class ExampleService {
    constructor(
        private readonly cacheService:RedisCacheService,
        private readonly publishService:RedisPublishService,

                ) {
    }
    async getExample() {
        return this.cacheService.get("example");
    }

    async setExample(value:string){
        await this.publishService.emit("example:set",value);
        return this.cacheService.set("example",value);
    }
}

My problem is I got this error everytime I publish event to redis

[admin-service] error   2022-09-03 17:36:15 connect ECONNREFUSED 127.0.0.1:6379 - {"stack":["ClientProxy"],"errno":-111,"code":"ECONNREFUSED","syscall":"connect","address":"127.0.0.1","port":6379} +18s
2022-09-03T10:36:15.377101300Z [admin-service] error    2022-09-03 17:36:15 connect ECONNREFUSED 127.0.0.1:6379 - {"stack":["ClientProxy"],"errno":-111,"code":"ECONNREFUSED","syscall":"connect","address":"127.0.0.1","port":6379} +9ms
2022-09-03T10:36:15.378503300Z [admin-service] error    2022-09-03 17:36:15 Retry time exhausted - {"stack":["ClientProxy"]} +2ms
2022-09-03T10:36:15.381020100Z [admin-service] error    2022-09-03 17:36:15 Retry time exhausted - {"stack":["ClientProxy"]} +2ms

I dont understand where did 127.0.0.1 coming from, as I set in my .env the REDIS_HOST to my redis in docker container

REDIS_HOST=redis-service-1
REDIS_PORT=6379
REDIS_PASSWORD=abc123yes

redis instance

Any advice would be really helpful, i’m stuck on this for 3 days

2

Answers


  1. I was stumped by this same thing for a good long while. It turns out that cache-manager-redis-store v3 does not accept a ‘host’ parameter, but instead just a redis url.

    Setting the URL with v3 resulted in a type mismatch for the store prop passed to the register function, so I simply downgraded cache-manager-redis-store to v2 in my package.json file. This solved the issue for me.

    In package.json:

    +    "cache-manager-redis-store": "^2",
    -    "cache-manager-redis-store": "^3.0.1",
    

    Then npm install

    Login or Signup to reply.
  2. I had the same issue, then I realized the syntax for Redis configuration on "cache-manager-redis-store" version 2.x.x and version 3.x.x.

    in version 2 you could configure as shown below

    {
         store: redisStore,
         host: 'localhost', // default value
         port: 6379, // default value 
         ttl: 600
     }
    

    but in version 3.x.x your need to add a socket payload

    {
         store: redisStore,
         socket: {
         host: 'localhost', // default value
         port: 6379, // default value 
         },
         ttl: 600
     }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search