4

I'm implementing a scoped container architecture such that a new container is created for every Express request (or apollographql request). I have a lifecycle method that can be called after we're done sending the response, which is good for cleaning up and freeing memory, and this method can reference the context of the request we're done serving. In that context I have a reference to the inversifyjs container that I created earlier so I can reference that container in the cleanup method, how can I delete that container?

function ScopedContainer(userId: number) {
  const container = new Container();
  container.bind<number>(TYPES.userId).toConstantValue(userId);
  //rest of bindings container.bind ...
  return container;
}

async({req, res}) => {
  const { headers } = req;
  const { userId } = headers;
  const container = ScopedContainer(clientId);
  const context = { container }
  ///...
}

willSendResponse(({container}) => {
  // how to instruct inversifyjs to ditch all references to container?
  // something like container.destroy?
});


I want to make sure that this container will not stay there after the http request is done, causing huge memory leak. Problem is I'm not sure it will be garbage collected as reference count reaches zeros. I'm also using lazyInject from inversify-inject-decorators

Is there any inversifyjs container API like destroy or reset method?

doc_id
  • 1,291
  • 11
  • 35

1 Answers1

3

There's no persistent reference to container instance inside inversify lib. It is temporarily ref'ed by Context in _planAndResolve private method, but is released upon return so no worry.

Conceptually, a container instance should be the top level resolver. All other services in the system are sorta "owned" by container, but nobody should own container except userland code.

En bref, as long as you stick to the rule: only use container in your composition root, like in inversify.config.ts, you're safe.

In your example it's less obvious how many other entities get hold to the container reference. If it's only the context object that you pass along express middlewares, then as soon as the request handling is done, context is deref'ed and so is container waiting to be GC. No further "cleanup" necessary.

hackape
  • 11,966
  • 1
  • 15
  • 40
  • Is there a way for a non-express (frontend instead of backend) project to keep a single container reference, and reset it in a way that it will recreate a new instance of the services I need to inject/get? – Zorgatone Mar 26 '21 at 10:48
  • Sure. Container only helps with the IoC pattern, as of how would you like to consume it, it's totally up to you. Just think of it as a master entity that spawns worker/service instances. And you're free to put yet another supervising entity on top of that master (container). – hackape Mar 26 '21 at 11:55
  • What about resetting that instance without making a new container? Is there an API/trick to do that? – Zorgatone Mar 26 '21 at 12:13
  • @Zorgatone How about post another question with some code to show the problem? I can take a look. – hackape Mar 26 '21 at 15:22
  • https://stackoverflow.com/questions/66820199 @hackape – Zorgatone Mar 26 '21 at 15:52