cache.service.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import { Injectable } from '@nestjs/common';
  2. import { JsonCompatible } from '@vendure/common/lib/shared-types';
  3. import { ConfigService } from '../config/config.service';
  4. import { Logger } from '../config/index';
  5. import { CacheStrategy, SetCacheKeyOptions } from '../config/system/cache-strategy';
  6. import { Cache, CacheConfig } from './cache';
  7. /**
  8. * @description
  9. * The CacheService is used to cache data in order to optimize performance.
  10. *
  11. * Internally it makes use of the configured {@link CacheStrategy} to persist
  12. * the cache into a key-value store.
  13. *
  14. * @since 3.1.0
  15. * @docsCategory cache
  16. */
  17. @Injectable()
  18. export class CacheService {
  19. protected cacheStrategy: CacheStrategy;
  20. constructor(private configService: ConfigService) {
  21. this.cacheStrategy = this.configService.systemOptions.cacheStrategy;
  22. }
  23. /**
  24. * @description
  25. * Creates a new {@link Cache} instance with the given configuration.
  26. *
  27. * The `Cache` instance provides a convenience wrapper around the `CacheService`
  28. * methods.
  29. */
  30. createCache(config: CacheConfig): Cache {
  31. return new Cache(config, this);
  32. }
  33. /**
  34. * @description
  35. * Gets an item from the cache, or returns undefined if the key is not found, or the
  36. * item has expired.
  37. */
  38. async get<T extends JsonCompatible<T>>(key: string): Promise<T | undefined> {
  39. try {
  40. const result = await this.cacheStrategy.get(key);
  41. if (result) {
  42. Logger.debug(`CacheService hit for key [${key}]`);
  43. }
  44. return result as T;
  45. } catch (e: any) {
  46. Logger.error(`Could not get key [${key}] from CacheService`, undefined, e.stack);
  47. }
  48. }
  49. /**
  50. * @description
  51. * Sets a key-value pair in the cache. The value must be serializable, so cannot contain
  52. * things like functions, circular data structures, class instances etc.
  53. *
  54. * Optionally a "time to live" (ttl) can be specified, which means that the key will
  55. * be considered stale after that many milliseconds.
  56. */
  57. async set<T extends JsonCompatible<T>>(
  58. key: string,
  59. value: T,
  60. options?: SetCacheKeyOptions,
  61. ): Promise<void> {
  62. try {
  63. await this.cacheStrategy.set(key, value, options);
  64. Logger.debug(`Set key [${key}] in CacheService`);
  65. } catch (e: any) {
  66. Logger.error(`Could not set key [${key}] in CacheService`, undefined, e.stack);
  67. }
  68. }
  69. /**
  70. * @description
  71. * Deletes an item from the cache.
  72. */
  73. async delete(key: string): Promise<void> {
  74. try {
  75. await this.cacheStrategy.delete(key);
  76. Logger.debug(`Deleted key [${key}] from CacheService`);
  77. } catch (e: any) {
  78. Logger.error(`Could not delete key [${key}] from CacheService`, undefined, e.stack);
  79. }
  80. }
  81. /**
  82. * @description
  83. * Deletes all items from the cache which contain at least one matching tag.
  84. */
  85. async invalidateTags(tags: string[]): Promise<void> {
  86. try {
  87. await this.cacheStrategy.invalidateTags(tags);
  88. Logger.debug(`Invalidated tags [${tags.join(', ')}] from CacheService`);
  89. } catch (e: any) {
  90. Logger.error(
  91. `Could not invalidate tags [${tags.join(', ')}] from CacheService`,
  92. undefined,
  93. e.stack,
  94. );
  95. }
  96. }
  97. }