feat: implement Redis caching for business activities and consumers
- Added Redis caching to BusinessActivitiesService for findAll and findOne methods. - Integrated Redis caching in BusinessActivityComplexesService for findAll and findOne methods. - Enhanced ConsumersService with Redis caching for findAll and findOne methods. - Introduced cache invalidation for partner consumers and business activities. - Created RedisKeyMaker utility for generating cache keys for consumers, partners, and POS. - Implemented cache invalidation services for partners and POS. - Added Redis service methods for JSON handling and key deletion by patterns. - Updated goods service to include caching and invalidation for goods list. - Introduced DTO for updating goods.
This commit is contained in:
@@ -1,9 +1,22 @@
|
||||
import { Global, Module } from '@nestjs/common'
|
||||
import { AdminGuildCacheInvalidationService } from '@/modules/admin/guilds/cache/admin-guild-cache-invalidation.service'
|
||||
import { PartnersCacheInvalidationService } from '@/modules/partners/cache/partners-cache-invalidation.service'
|
||||
import { PosCacheInvalidationService } from '@/modules/pos/cache/pos-cache-invalidation.service'
|
||||
import { RedisService } from './redis.service'
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [RedisService],
|
||||
exports: [RedisService],
|
||||
providers: [
|
||||
RedisService,
|
||||
AdminGuildCacheInvalidationService,
|
||||
PartnersCacheInvalidationService,
|
||||
PosCacheInvalidationService,
|
||||
],
|
||||
exports: [
|
||||
RedisService,
|
||||
AdminGuildCacheInvalidationService,
|
||||
PartnersCacheInvalidationService,
|
||||
PosCacheInvalidationService,
|
||||
],
|
||||
})
|
||||
export class RedisModule {}
|
||||
|
||||
@@ -34,6 +34,99 @@ export class RedisService implements OnModuleDestroy {
|
||||
return this.client
|
||||
}
|
||||
|
||||
async get(key: string): Promise<string | null> {
|
||||
const client = await this.getClient()
|
||||
return client.get(key)
|
||||
}
|
||||
|
||||
async getJson<T>(key: string): Promise<T | null> {
|
||||
const value = await this.get(key)
|
||||
if (!value) {
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(value) as T
|
||||
} catch {
|
||||
this.logger.warn(`Invalid JSON for key "${key}"`)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async set(
|
||||
key: string,
|
||||
value: string,
|
||||
ttlSeconds?: number,
|
||||
): Promise<'OK' | null> {
|
||||
const client = await this.getClient()
|
||||
if (ttlSeconds && ttlSeconds > 0) {
|
||||
return client.set(key, value, 'EX', ttlSeconds)
|
||||
}
|
||||
return client.set(key, value)
|
||||
}
|
||||
|
||||
async setJson(
|
||||
key: string,
|
||||
value: unknown,
|
||||
ttlSeconds?: number,
|
||||
): Promise<'OK' | null> {
|
||||
return this.set(key, JSON.stringify(value), ttlSeconds)
|
||||
}
|
||||
|
||||
async delete(key: string): Promise<number> {
|
||||
const client = await this.getClient()
|
||||
return client.del(key)
|
||||
}
|
||||
|
||||
async exists(key: string): Promise<boolean> {
|
||||
const client = await this.getClient()
|
||||
const result = await client.exists(key)
|
||||
return result === 1
|
||||
}
|
||||
|
||||
async expire(key: string, ttlSeconds: number): Promise<boolean> {
|
||||
const client = await this.getClient()
|
||||
const result = await client.expire(key, ttlSeconds)
|
||||
return result === 1
|
||||
}
|
||||
|
||||
async deleteByPattern(pattern: string): Promise<number> {
|
||||
const client = await this.getClient()
|
||||
let deletedCount = 0
|
||||
let cursor = '0'
|
||||
|
||||
do {
|
||||
const [nextCursor, keys] = await client.scan(
|
||||
cursor,
|
||||
'MATCH',
|
||||
pattern,
|
||||
'COUNT',
|
||||
100,
|
||||
)
|
||||
cursor = nextCursor
|
||||
|
||||
if (keys.length > 0) {
|
||||
const pipeline = client.pipeline()
|
||||
keys.forEach(k => pipeline.del(k))
|
||||
const results = await pipeline.exec()
|
||||
if (results) {
|
||||
deletedCount += results.reduce((sum, [, value]) => {
|
||||
return sum + (typeof value === 'number' ? value : 0)
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
} while (cursor !== '0')
|
||||
|
||||
return deletedCount
|
||||
}
|
||||
|
||||
async deleteByPatterns(patterns: string[]): Promise<number> {
|
||||
const deletedCounts = await Promise.all(
|
||||
patterns.map(pattern => this.deleteByPattern(pattern)),
|
||||
)
|
||||
return deletedCounts.reduce((sum, count) => sum + count, 0)
|
||||
}
|
||||
|
||||
async onModuleDestroy() {
|
||||
await this.client.quit()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user