Feature/improve redis cache (#3714)

* Improve redis cache

* Update changelog
This commit is contained in:
Thomas Kaul
2024-08-31 10:57:26 +02:00
committed by GitHub
parent 267023f2c9
commit 0fc83486dc
10 changed files with 180 additions and 110 deletions

View File

@@ -1,7 +0,0 @@
import { Cache } from 'cache-manager';
import type { RedisStore } from './redis-store.interface';
export interface RedisCache extends Cache {
store: RedisStore;
}

View File

@@ -1,8 +0,0 @@
import { Store } from 'cache-manager';
import { createClient } from 'redis';
export interface RedisStore extends Store {
getClient: () => ReturnType<typeof createClient>;
isCacheableValue: (value: any) => boolean;
name: 'redis';
}

View File

@@ -3,31 +3,27 @@ import { ConfigurationService } from '@ghostfolio/api/services/configuration/con
import { CacheModule } from '@nestjs/cache-manager';
import { Module } from '@nestjs/common';
import * as redisStore from 'cache-manager-redis-store';
import { redisStore } from 'cache-manager-redis-yet';
import type { RedisClientOptions } from 'redis';
import { RedisCacheService } from './redis-cache.service';
@Module({
exports: [RedisCacheService],
imports: [
CacheModule.registerAsync({
CacheModule.registerAsync<RedisClientOptions>({
imports: [ConfigurationModule],
inject: [ConfigurationService],
useFactory: async (configurationService: ConfigurationService) => {
return <RedisClientOptions>{
db: configurationService.get('REDIS_DB'),
host: configurationService.get('REDIS_HOST'),
max: configurationService.get('MAX_ITEM_IN_CACHE'),
password: configurationService.get('REDIS_PASSWORD'),
port: configurationService.get('REDIS_PORT'),
store: redisStore,
ttl: configurationService.get('CACHE_TTL')
ttl: configurationService.get('CACHE_TTL'),
url: `redis://:${configurationService.get('REDIS_PASSWORD')}@${configurationService.get('REDIS_HOST')}:${configurationService.get('REDIS_PORT')}/${configurationService.get('REDIS_DB')}`
};
}
}),
ConfigurationModule
],
providers: [RedisCacheService],
exports: [RedisCacheService]
providers: [RedisCacheService]
})
export class RedisCacheModule {}

View File

@@ -1,4 +1,4 @@
import { RedisCacheService } from './redis-cache.service';
import { Milliseconds } from 'cache-manager';
export const RedisCacheServiceMock = {
get: (key: string): Promise<string> => {
@@ -7,7 +7,7 @@ export const RedisCacheServiceMock = {
getPortfolioSnapshotKey: (userId: string): string => {
return `portfolio-snapshot-${userId}`;
},
set: (key: string, value: string, ttlInSeconds?: number): Promise<string> => {
set: (key: string, value: string, ttl?: Milliseconds): Promise<string> => {
return Promise.resolve(value);
}
};

View File

@@ -4,17 +4,17 @@ import { AssetProfileIdentifier, Filter } from '@ghostfolio/common/interfaces';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Inject, Injectable, Logger } from '@nestjs/common';
import { Milliseconds } from 'cache-manager';
import { RedisCache } from 'cache-manager-redis-yet';
import { createHash } from 'crypto';
import type { RedisCache } from './interfaces/redis-cache.interface';
@Injectable()
export class RedisCacheService {
public constructor(
@Inject(CACHE_MANAGER) private readonly cache: RedisCache,
private readonly configurationService: ConfigurationService
) {
const client = cache.store.getClient();
const client = cache.store.client;
client.on('error', (error) => {
Logger.error(error, 'RedisCacheService');
@@ -81,11 +81,11 @@ export class RedisCacheService {
return this.cache.reset();
}
public async set(key: string, value: string, ttlInSeconds?: number) {
public async set(key: string, value: string, ttl?: Milliseconds) {
return this.cache.set(
key,
value,
ttlInSeconds ?? this.configurationService.get('CACHE_TTL')
ttl ?? this.configurationService.get('CACHE_TTL')
);
}
}

View File

@@ -21,7 +21,7 @@ export class ConfigurationService {
API_KEY_FINANCIAL_MODELING_PREP: str({ default: '' }),
API_KEY_OPEN_FIGI: str({ default: '' }),
API_KEY_RAPID_API: str({ default: '' }),
CACHE_QUOTES_TTL: num({ default: ms('1 minute') / 1000 }),
CACHE_QUOTES_TTL: num({ default: ms('1 minute') }),
CACHE_TTL: num({ default: 1 }),
DATA_SOURCE_EXCHANGE_RATES: str({ default: DataSource.YAHOO }),
DATA_SOURCE_IMPORT: str({ default: DataSource.YAHOO }),
@@ -43,7 +43,6 @@ export class ConfigurationService {
JWT_SECRET_KEY: str({}),
MAX_ACTIVITIES_TO_IMPORT: num({ default: Number.MAX_SAFE_INTEGER }),
MAX_CHART_ITEMS: num({ default: 365 }),
MAX_ITEM_IN_CACHE: num({ default: 9999 }),
PORT: port({ default: 3333 }),
REDIS_DB: num({ default: 0 }),
REDIS_HOST: str({ default: 'localhost' }),

View File

@@ -29,7 +29,6 @@ export interface Environment extends CleanedEnvAccessors {
JWT_SECRET_KEY: string;
MAX_ACTIVITIES_TO_IMPORT: number;
MAX_CHART_ITEMS: number;
MAX_ITEM_IN_CACHE: number;
PORT: number;
REDIS_DB: number;
REDIS_HOST: string;