Feature/improve redis cache (#3714)
* Improve redis cache * Update changelog
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
import { Cache } from 'cache-manager';
|
||||
|
||||
import type { RedisStore } from './redis-store.interface';
|
||||
|
||||
export interface RedisCache extends Cache {
|
||||
store: RedisStore;
|
||||
}
|
@@ -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';
|
||||
}
|
@@ -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 {}
|
||||
|
@@ -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);
|
||||
}
|
||||
};
|
||||
|
@@ -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')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -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' }),
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user