Skip to content

Pass a per-delivery key to ContainerAdapter.get, so request scopes aren't shared across retries #353

Description

@adenhertog

Follow-up from #352 (NestJS integration).

Problem

ContainerAdapter.get(type, context) is given { message, messageAttributes }. Nothing in that context identifies one delivery of a message. nestContainer() in @node-ts/bus-nestjs keys its per-message request scope (ContextId) by the message object, which is the only stable key it has.

That works for transports that deserialize each delivery into a new object. But InMemoryQueue retries a returned message, and re-sends the same object, without copying it. So every retry of a message shares the request-scoped instances, and the REQUEST, of its first attempt. State that a request-scoped provider builds up during a failed attempt leaks into the retry. Any other container adapter that scopes per message has the same problem.

Proposal

Have bus-core pass a per-delivery key in the container context: for example the TransportMessage being handled, which is a new object for each delivery and is already what the handling context tracks. Then nestContainer() can key its scope on that rather than on the message.

  • Class handlers: invokeHandler in service-bus/bus-instance.ts calls container.get(classHandler, { message, messageAttributes }).
  • Class workflows: invokerFor in workflow/registry/workflow-registry.ts calls container.get(WorkflowCtor, { message, messageAttributes }).
  • Adding an optional field to the context is not a breaking change for adapters.

Metadata

Metadata

Assignees

No one assigned

    Labels

    roadmapPart of the project roadmap

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions