Skip to content

Commit

Permalink
Add cache-flush step in Twenty upgrade command twentyhq#7521 (twentyh…
Browse files Browse the repository at this point in the history
…q#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 <[email protected]>
  • Loading branch information
2 people authored and harshit078 committed Oct 14, 2024
1 parent 843d481 commit 5608e3c
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
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 { 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';

// TODO: implement dry-run
@Command({
name: 'cache:flush',
description: 'Completely flush cache',
description: 'Flush cache for specific keys matching the pattern',
})
export class FlushCacheCommand extends CommandRunner {
private readonly logger = new Logger(FlushCacheCommand.name);
Expand All @@ -21,9 +20,28 @@ export class FlushCacheCommand extends CommandRunner {
super();
}

async run(): Promise<void> {
this.logger.log('Flushing cache...');
await this.cacheStorage.flush();
async run(
passedParams: string[],
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');
}

@Option({
flags: '-p, --pattern <pattern>',
description: 'Pattern to flush specific cache keys (e.g., engine:*)',
})
parsePattern(val: string): string {
return val;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Inject, Injectable } from '@nestjs/common';
import { CACHE_MANAGER, Cache } from '@nestjs/cache-manager';
import { Inject, Injectable } from '@nestjs/common';

import { RedisCache } from 'cache-manager-redis-yet';

Expand Down Expand Up @@ -67,6 +67,31 @@ export class CacheStorageService {
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() {
return (this.cache.store as any)?.name === 'redis';
}
Expand Down

0 comments on commit 5608e3c

Please sign in to comment.