Flush Specific Redis Keys After Upgrade Command :---- Changes Made :---- Updated the FlushCacheCommand to allow for selective flushing of keys that match the pattern engine:*, rather than flushing the entire cache. Added a new optional parameter to specify the cache keys pattern. Ensured that the cache is flushed at the end of the upgrade command. Code Changes :---- Modified FlushCacheCommand to include a method for flushing keys by pattern. Added a new function in CacheStorageService to handle the pattern-based flushing. --------- Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
@ -1,15 +1,14 @@
|
|||||||
import { Logger } from '@nestjs/common';
|
import { Logger } from '@nestjs/common';
|
||||||
|
|
||||||
import { Command, CommandRunner } from 'nest-commander';
|
import { Command, CommandRunner, Option } from 'nest-commander';
|
||||||
|
|
||||||
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
|
import { InjectCacheStorage } from 'src/engine/core-modules/cache-storage/decorators/cache-storage.decorator';
|
||||||
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
|
import { CacheStorageService } from 'src/engine/core-modules/cache-storage/services/cache-storage.service';
|
||||||
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
|
import { CacheStorageNamespace } from 'src/engine/core-modules/cache-storage/types/cache-storage-namespace.enum';
|
||||||
|
|
||||||
// TODO: implement dry-run
|
|
||||||
@Command({
|
@Command({
|
||||||
name: 'cache:flush',
|
name: 'cache:flush',
|
||||||
description: 'Completely flush cache',
|
description: 'Flush cache for specific keys matching the pattern',
|
||||||
})
|
})
|
||||||
export class FlushCacheCommand extends CommandRunner {
|
export class FlushCacheCommand extends CommandRunner {
|
||||||
private readonly logger = new Logger(FlushCacheCommand.name);
|
private readonly logger = new Logger(FlushCacheCommand.name);
|
||||||
@ -21,9 +20,28 @@ export class FlushCacheCommand extends CommandRunner {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
async run(): Promise<void> {
|
async run(
|
||||||
this.logger.log('Flushing cache...');
|
passedParams: string[],
|
||||||
await this.cacheStorage.flush();
|
options?: Record<string, any>,
|
||||||
|
): Promise<void> {
|
||||||
|
const pattern = options?.pattern || '*';
|
||||||
|
|
||||||
|
this.logger.log(`Flushing cache for pattern: ${pattern}...`);
|
||||||
|
|
||||||
|
if (pattern === '*') {
|
||||||
|
await this.cacheStorage.flush();
|
||||||
|
} else {
|
||||||
|
await this.cacheStorage.flushByPattern(pattern);
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.log('Cache flushed');
|
this.logger.log('Cache flushed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Option({
|
||||||
|
flags: '-p, --pattern <pattern>',
|
||||||
|
description: 'Pattern to flush specific cache keys (e.g., engine:*)',
|
||||||
|
})
|
||||||
|
parsePattern(val: string): string {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Inject, Injectable } from '@nestjs/common';
|
|
||||||
import { CACHE_MANAGER, Cache } from '@nestjs/cache-manager';
|
import { CACHE_MANAGER, Cache } from '@nestjs/cache-manager';
|
||||||
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import { RedisCache } from 'cache-manager-redis-yet';
|
import { RedisCache } from 'cache-manager-redis-yet';
|
||||||
|
|
||||||
@ -67,6 +67,31 @@ export class CacheStorageService {
|
|||||||
return this.cache.reset();
|
return this.cache.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async flushByPattern(scanPattern: string): Promise<void> {
|
||||||
|
if (!this.isRedisCache()) {
|
||||||
|
throw new Error('flushByPattern is only supported with Redis cache');
|
||||||
|
}
|
||||||
|
|
||||||
|
const redisClient = (this.cache as RedisCache).store.client;
|
||||||
|
let cursor = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
const result = await redisClient.scan(cursor, {
|
||||||
|
MATCH: scanPattern,
|
||||||
|
COUNT: 100,
|
||||||
|
});
|
||||||
|
|
||||||
|
const nextCursor = result.cursor;
|
||||||
|
const keys = result.keys;
|
||||||
|
|
||||||
|
if (keys.length > 0) {
|
||||||
|
await redisClient.del(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor = nextCursor;
|
||||||
|
} while (cursor !== 0);
|
||||||
|
}
|
||||||
|
|
||||||
private isRedisCache() {
|
private isRedisCache() {
|
||||||
return (this.cache.store as any)?.name === 'redis';
|
return (this.cache.store as any)?.name === 'redis';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user