Skip to content

Create factory for CacheClient #4558

@konstantinabl

Description

@konstantinabl

Problem

Currently, we pass the redisClient to our CacheService, which may be undefined. Based on this value the CacheService decides if it needs to initialize LRUCache or RedisCache, however passing redisClient as undefined breaks the Interface segregation principle.

class CacheService implements ICacheClient {
  //.....
  public constructor(
    logger: Logger,
    register: Registry = new Registry(),
    reservedKeys: Set<string> = new Set(),
    redisClient?: RedisClientType,
  ) {
    this.logger = logger;
    this.register = register;

    this.internalCache = new LocalLRUCache(logger.child({ name: 'localLRUCache' }), register, reservedKeys);
    this.sharedCache = this.internalCache;
    this.isSharedCacheEnabled = !ConfigService.get('TEST') && redisClient !== undefined;
    this.shouldMultiSet = ConfigService.get('MULTI_SET');

    if (this.isSharedCacheEnabled) {
      this.sharedCache = new RedisCache(logger.child({ name: 'redisCache' }), register, redisClient!);
    }
    //.......
}

Solution

Create a factory class creating either LRUCache or RedisCache and pass them to CacheService

export class CacheFactory {
  static create(redisClient?: RedisClientType): CacheClient {
    return redisClient 
      ? new RedisCache(redisClient)
      : new LRUCache();
  }
}

// In Relay
const cache = CacheFactory.create(this.redisClient);
new CacheService(cache, ...)

Benefits

  • Encapsulates cache selection logic
  • Cache service does not deal with creating cache classes
  • Easier to add new cache types
  • Stick to the interface segregation principle

Metadata

Metadata

Assignees

Labels

Technical DebtIssue which resolves technical debtinternalFor changes that affect the project's internal workings but not its outward-facing functionality.

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions