Papooch / nestjs-cls

A continuation-local storage (async context) module compatible with NestJS's dependency injection.
https://papooch.github.io/nestjs-cls/
MIT License
389 stars 23 forks source link

Duplicate IDs when using Microservices (Kafka) #127

Closed hjf closed 3 months ago

hjf commented 3 months ago

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; }
      },
    }),

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()),
      },
    }),
Papooch commented 3 months ago

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.

Papooch commented 3 months ago

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