dabroek / node-cache-manager-redis-store

Redis store for node-cache-manager using node_redis.
MIT License
171 stars 59 forks source link

Upgrade redis to v4 #40

Open dantehemerson opened 2 years ago

dantehemerson commented 2 years ago

To use newest types features for typescript and avoid errors with types when using latest 3.x versions

mengtongun commented 1 year ago

This is my solution, works with latest version implement same as @jlopez994 :

import { RedisClientOptions } from 'redis';
import { redisStore } from 'cache-manager-redis-yet';
import { ConfigModule, ConfigService } from '@nestjs/config';
CacheModule.registerAsync<RedisClientOptions>({
  imports: [ConfigModule],
  useFactory: async (cfg: ConfigService) => ({
    store: await redisStore({
     socket: {
       host: cfg.get('REDIS_HOST'),
       port: parseInt(cfg.get('REDIS_PORT ') || '6379'),
     },
     password: cfg.get('REDIS_PASSWORD'),
     ttl: cfg.get('REDIS_TTL'),
   }),
  }),
  inject: [ConfigService]
}),
"@nestjs/common": "^10.0.5",
"cache-manager": "^5.2.3",
"cache-manager-redis-yet": "^4.1.2",
"redis": "^4.6.7",

This worked for me.

elouizbadr commented 1 year ago

This is my solution, works with latest version implement same as @jlopez994 :

import { RedisClientOptions } from 'redis';
import { redisStore } from 'cache-manager-redis-yet';
import { ConfigModule, ConfigService } from '@nestjs/config';
CacheModule.registerAsync<RedisClientOptions>({
 imports: [ConfigModule],
 useFactory: async (cfg: ConfigService) => ({
   store: await redisStore({
    socket: {
      host: cfg.get('REDIS_HOST'),
      port: parseInt(cgf.get('REDIS_PORT ') || '6379'),
    },
    password: cfg.get('REDIS_PASSWORD'),
    ttl: cfg.get('REDIS_TTL'),
  }),
 }),
 inject: [ConfigService]
}),
"@nestjs/common": "^10.0.5",
"cache-manager": "^5.2.3",
"cache-manager-redis-yet": "^4.1.2",
"redis": "^4.6.7",

This worked for me.

  • CacheTTL() worked fine.
  • Cache Manager set: (key: string, value: unknown, ttl?: number) also worked fine.

Thank you @mengtongun for this solution. Just a side note, you've got a typo in the following line (Where cgf should be cfg):

port: parseInt(cgf.get('REDIS_PORT ') || '6379'),
SlinkyPotato commented 1 year ago

This is interesting.

A few things:

The last commit from this project was October 16 2022.

This project is forked to https://github.com/node-cache-manager/node-cache-manager-redis-yet#license

It is officially maintained by node-cache-manager according to NestJS docs https://docs.nestjs.com/techniques/caching#different-stores https://github.com/node-cache-manager/node-cache-manager#store-engines

Is this project abandoned?

Here is a working example from node-cache-manager-redis-yet

import { CacheModule } from '@nestjs/cache-manager';
import { RedisClientOptions } from 'redis';
import { redisStore } from 'cache-manager-redis-yet';

@Module({
  imports: [
    CacheModule.register<RedisClientOptions>({
      store: redisStore,
      socket: {
        host: process.env.REDIS_HOST ?? 'localhost',
        port: parseInt(process.env.REDIS_PORT ?? '6379'),
      },
    }),
  ],
})
export class TestModule {}
...
constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
...
await this.cacheManager.set('test', 'test-value');
const testVal = await this.cacheManager.get('test');
...
"@nestjs/common": "^10.0.5",
"cache-manager": "^5.2.3",
"cache-manager-redis-yet": "^4.1.2",
"redis": "^4.6.7",
Biigode commented 1 year ago

This is interesting.

A few things:

The last commit from this project was October 16 2022.

This project is forked to https://github.com/node-cache-manager/node-cache-manager-redis-yet#license

It is officially maintained by node-cache-manager according to NestJS docs https://docs.nestjs.com/techniques/caching#different-stores

Is this project abandoned?

Here is a working example from node-cache-manager-redis-yet

import { CacheModule } from '@nestjs/cache-manager';
import { RedisClientOptions } from 'redis';
import { redisStore } from 'cache-manager-redis-yet';

@Module({
  imports: [
    CacheModule.register<RedisClientOptions>({
      store: redisStore,
      socket: {
        host: process.env.REDIS_HOST ?? 'localhost',
        port: parseInt(process.env.REDIS_PORT ?? '6379'),
      },
    }),
  ],
})
export class TestModule {}
...
constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
...
await this.cacheManager.set('test', 'test-value');
const testVal = await this.cacheManager.get('test');
...
"@nestjs/common": "^10.0.5",
"cache-manager": "^5.2.3",
"cache-manager-redis-yet": "^4.1.2",
"redis": "^4.6.7",

This solutions works for me thanks. Follow the images

image

image

image

zenstok commented 1 year ago

Please be cautious regarding this issue that I came across while using cache-manager-redis-yet. This issue could potentially lead to a security vulnerability within your application, especially if you are depending on the @Exclude() class validator decorator to conceal attributes from the frontend.

NinjaMax commented 1 year ago

Maybe I can help someone. In my case :

With TTL - this is workes for me.

import { CacheStore, Module } from '@nestjs/common';
import { RedisClientOptions, createClient } from 'redis';
import { CacheModule } from '@nestjs/cache-manager';
//--------------------------------------------------------
CacheModule.registerAsync<RedisClientOptions>({
      imports: [ConfigModule.register({ folder: './config' })],
      useFactory: async (configService: ConfigService) => {
        const store = createClient({
          socket: {
            host: configService.get('REDIS_HOST'),
            port: +configService.get('REDIS_PORT'), 
          },
        });
        await store.connect().catch(console.error);
        const redisStore = new RedisStore({
          client: store,
          prefix: 'tyre-no-offset: ', 
          ttl: 5000,
        });
        return { store: redisStore as unknown as CacheStore };
      },
      isGlobal: true,
      inject: [ConfigService],
    }),
//--------------------------------------------

controller:

  @UseInterceptors(CacheInterceptor)
  @CacheKey('no-offset')
  @Get('/no-offset')
  findTyresWithoutLimit(@Query('width') width: string,) {
    return this.tyresService.findAllTyresWithoutOffset(width);
  }
mohit4bug commented 7 months ago

Seems to work!

import { AppController } from "@/app.controller"
import { AppService } from "@/app.service"
import { CacheModule } from "@nestjs/cache-manager"
import { Module } from "@nestjs/common"
import { ConfigModule, ConfigService } from "@nestjs/config"
import { redisStore } from "cache-manager-redis-yet"
import type { RedisClientOptions } from "redis"

@Module({
  imports: [
    CacheModule.registerAsync<RedisClientOptions>({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => ({
        store: await redisStore({
          ttl: parseInt(configService.get<string>("REDIS_TTL")),
          socket: {
            host: configService.get<string>("REDIS_HOST"),
            port: parseInt(configService.get<string>("REDIS_PORT")),
          },
        }),
      }),
      isGlobal: true,
    }),
    ConfigModule.forRoot({
      isGlobal: true,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
ygweric commented 7 months ago
  • set: (key: string, value: unknown, ttl?: number) also doesn't worked.

same bug with me

kokole12 commented 6 months ago

This worked for me so far `/ eslint-disable @typescript-eslint/ban-ts-comment / import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { APP_INTERCEPTOR } from '@nestjs/core'; import { CacheInterceptor, CacheModule } from '@nestjs/cache-manager'; import { RedisClientOptions } from 'redis'; import { redisStore } from 'cache-manager-redis-store';

@Module({ imports: [ CacheModule.register({ // @ts-ignore store: async () => await redisStore({ socket: { host: 'localhost', port: 6379, }, }), }), ], controllers: [AppController], providers: [ AppService, { provide: APP_INTERCEPTOR, useClass: CacheInterceptor, }, ], }) export class AppModule {}

pedroaraujo1952 commented 5 months ago

Any update on when will this be completed?

toknT commented 4 months ago

Hi it's 2024, and I am using redis v5

for redis v5 , use cache-manager-redis-yet

https://github.com/dabroek/node-cache-manager-redis-store/issues/40#issuecomment-2260672349

samuelgoldenbaum commented 4 months ago

Using the following does not close the redis connection when app.close() is called and will also leave your tests hanging.

CacheModule.registerAsync<RedisClientOptions>({
      useFactory: async (configService: AppConfigService) => ({
        store: await redisStore({
          ttl: configService.cache.ttl,
          socket: {
            host: configService.cache.host,
            port: configService.cache.port
          }
        })
      }),
      inject: [AppConfigService],
      isGlobal: true
    }),

I had to implement the following to manually close the client:

export class AppModule implements OnModuleDestroy {
     constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}

     async onModuleDestroy() {
       // @ts-expect-error as store.client is not currently exposed
       await this.cacheManager.store.client.quit()
     }
}
MaazEllahiKhan commented 3 months ago

update: double check the port you are running redis server on, I changed mine to 10001 and was trying to access it on 6379 (I was getting no error). Don't be like me. The configurations were working fine both redis-yet and redis-store 2.0.0.

Seems to work!

import { AppController } from "@/app.controller"
import { AppService } from "@/app.service"
import { CacheModule } from "@nestjs/cache-manager"
import { Module } from "@nestjs/common"
import { ConfigModule, ConfigService } from "@nestjs/config"
import { redisStore } from "cache-manager-redis-yet"
import type { RedisClientOptions } from "redis"

@Module({
  imports: [
    CacheModule.registerAsync<RedisClientOptions>({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => ({
        store: await redisStore({
          ttl: parseInt(configService.get<string>("REDIS_TTL")),
          socket: {
            host: configService.get<string>("REDIS_HOST"),
            port: parseInt(configService.get<string>("REDIS_PORT")),
          },
        }),
      }),
      isGlobal: true,
    }),
    ConfigModule.forRoot({
      isGlobal: true,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

can u please share the packages with versions you are using? redis, cache-manager, redis-yet or redis-store? any other related? I have tried multiple configurations with different versions, cache-manager-ioredis-yet, cache-manager-redis-yet, cache-manager-redis-store with rediisIO, redis and multiple cache-manager packages from 3.0 to 5.0 but still unable to get data on store. I am getting undefined from set and get right now using your configurations. I was able to get ok from set but didn't find data on redis visualizer with cache-manager-redis-store pakage 2.0.0. Really stuck in this any help is welcome. My packages: cache-manager": "^5.2.3", "cache-manager-redis-yet": "^4.1.2", "redis": "^4.6.7",

minikdev commented 3 months ago

One regretful thing is that the ttl option is not applied when using cache manager's set method by injecting cache-manager in *.service.ts. Fortunately, the @CacheTTL() decorate is working.

It seems like set method expects ttl option as an object value not a number, which is misled by type definition.

https://github.com/dabroek/node-cache-manager-redis-store/blob/04d04cb5e5a472a9f8eb78c59fa1f90eb6df5839/index.js#L19

It works after I changed like below.

this.cacheManager.set("key", "value", { ttl: 10 } as any);

version

"cache-manager": "^5.1.3",
"cache-manager-redis-store": "^3.0.1",

thanks bro you saved me

ktphuc1994 commented 2 months ago

@assisgui same here but had to also configure the ttl:

CacheModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (config: ConfigService) => {
    const store = await redisStore({
      socket: {
        host: config.get('REDIS_HOST'),
        port: +config.get('REDIS_PORT'),
      },
      password: config.get('REDIS_PASSWORD'),
    });

    return {
      store: store as unknown as CacheStore,
      ttl: 60 * 60 * 24 * 7,
    };
  },
  inject: [ConfigService],
}),

This seems to work with latest packages, the former left the TTL to -1. Noticed cached items didn't expire and checked the database.

CacheModule.registerAsync({
    imports: [ConfigModule],
    useFactory: async (config: ConfigService) => {
        const store = await redisStore({
            socket: {
                host: config.get<string>('REDIS_HOST'),
                port: config.get<number>('REDIS_PORT'),
            },
            password: config.get<string>('REDIS_PASSWORD'),
            ttl: 60, // 60 seconds
        });

        return {
            store: store as unknown as CacheStore,
        };
    },
    inject: [ConfigService],
}),
 "@nestjs/cache-manager": "^1.0.0",
 "@nestjs/common": "^9.0.0",
 "redis": "^4.6.6",
 "cache-manager-redis-store": "^3.0.1",

This one is working for me. Current version:

 "@nestjs/cache-manager": "^2.2.2",
 "cache-manager": "^5.7.6",
 "redis": "^4.7.0",
 "cache-manager-redis-store": "^3.0.1",