Papooch / nestjs-cls

A continuation-local storage (async context) module compatible with NestJS's dependency injection.

Home Page:https://papooch.github.io/nestjs-cls/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Duplicate IDs when using Microservices (Kafka)

hjf opened this issue · comments

commented

When using nestjs-cls as a guard, with messages coming from a Kafka queue, the IDs obtained by getId are repeated for every request.

Example:

    ClsModule.forRoot({
      global: true,
      guard: {
        generateId: true,
        idGenerator: () => { const id = randomUUID(); console.log(id); return id; }
      },
    }),
  • The console.log in the generateId function shows that it's being called for every request
  • Using getId() at any service, guard, interceptor etc shows only the first ID logged by console.log
  • It happens only with Kafka, and not with HTTP services

Workaround:

as suggested by @Papooch in a Discord thread, this can be worked around using a setup function:

    ClsModule.forRoot({
      global: true,
      guard: {
        setup: (cls) => cls.set(CLS_ID, randomUUID()),
      },
    }),

Thank you for reporting the issue. This problem seems to be caused by a combination of (AsyncLocalStorage#enterWilth)[https://bitbucket.org/iotwaterdevelopers/smg_ns/pull-requests/1074], and using cls.enter({ idNested: 'reuse' }) which is used in the ClsGuard to setup the context.

Apparently, in the microservices context, the context leaks to the next call, making cls.enter re-use the existing context from the previous call. This is bad, unless you override all properties in the store before the program flow reaches business-logic. If you only use the ID, then it is probably fine. If you use other properties, make sure to set them to undefined in the setup method, too.

The safe way is to se ClsInterceptoruntil I figure out how to fix it for the guard as well.

@hjf I have pushed a fix in 4.2.1, please update the package and see if it is resolved now.