Add cache-flush step in Twenty upgrade command #7521 (#7553)

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:
shubham yadav
2024-10-10 19:35:09 +05:30
committed by GitHub
parent 9a77386917
commit bfc13b9647
2 changed files with 50 additions and 7 deletions

View File

@ -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;
}
} }

View File

@ -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';
} }