cache-manager icon indicating copy to clipboard operation
cache-manager copied to clipboard

CacheModule in multiple modules not loading the config properly

Open GustavoKatel opened this issue 2 years ago • 2 comments
trafficstars

Is there an existing issue for this?

  • [X] I have searched the existing issues

Current behavior

I have a helper function that creates the CacheModule dynamically based on some input. This function is called multiple times for different modules that rely on CacheModule.

The CacheModule however is not loading the settings correctly. Only one of the settings set are loaded and applied to all other modules using the same function.

function:

export function createCacheModule(options: CreateCacheModuleOptions) {
  options.inject = [ConfigService, ...(options.inject || [])];

  if (options.useFactory) {
    const inputFactory = options.useFactory;
    options.useFactory = async (configService: ConfigService) => {
      const opts = await inputFactory(configService);
      console.log({ opts });
      return opts;
    };
  }

  return CacheModule.registerAsync(options);
}

expected logs: image

current logs: image

in the second screenshot you can see that only the useFactory of AModule gets called and BModule gets the same config from AModule even though they are created differently.

Minimum reproduction code

https://github.com/GustavoKatel/nestjs-cache-module-test

Steps to reproduce

  1. npm ci
  2. npm run start
  3. check the logs

Expected behavior

I expected the ttl and all other settings to be different for in BModule, but insteead BModule got the same settings from AModule (see screenshots above)

Package version

2.1.1

NestJS version

10.2.8

Node.js version

21.1.0

In which operating systems have you tested?

  • [X] macOS
  • [ ] Windows
  • [ ] Linux

Other

No response

GustavoKatel avatar Nov 10 '23 14:11 GustavoKatel

I also ran into this. But after upgrading from 10.2.10 --> @nestjs/[email protected] and @nestjs/[email protected]. In thisprovided repo the tests fail , there is also a working branch.

drdreo avatar Jan 17 '24 08:01 drdreo

While testing with the following versions:

"@nestjs/cache-manager": "2.2.2",
"@nestjs/common": "^10.3.10",
"@nestjs/core": "^10.3.10"

the issue seems resolved, but a strange bug occurs when CacheModule is registered with the same configuration. It shares the same cache store even if it is imported by different modules. Here is the reproduction: https://codesandbox.io/p/devbox/nestjs-cache-register-bug-2snp4k?file=%2Fsrc%2Fapp.spec.ts

After investigation, I realized that the useFactory function provided by CACHE_MANAGER is only called when the options parameter is registered differently.

https://github.com/nestjs/cache-manager/blob/65d710179e3224fd2d8f3ef2ca09473f84a7e00f/lib/cache.providers.ts#L19

Is there any caching mechanism applied when initializing a dynamic provider here related to ConfigurableModuleBuilder? If so, I think we can fix this issue by generating a unique ID each time the CacheModule is registered, like the following:

static register<StoreConfig extends Record<any, any> = Record<string, any>>(
    options: CacheModuleOptions<StoreConfig> = {} as any,
  ): DynamicModule {
    return {
      global: options.isGlobal,
      ...super.register({ ...options, id: <UNIQUE_ID> }),
    };
  }

quangtran88 avatar Jul 09 '24 03:07 quangtran88

Fixed in this PR https://github.com/nestjs/nest/pull/13336

kamilmysliwiec avatar Oct 18 '24 12:10 kamilmysliwiec