Coder Social home page Coder Social logo

Comments (2)

jeffijoe avatar jeffijoe commented on June 2, 2024

Disabling the check for the AuthProviderService would remove the error, but I am also aware that may cause other issues (leak?).

It would not work the way you expect it to, because before the introduction of strict mode if you resolved a singleton through a scope, if that singleton depended on scoped services, it would maintain references to those scoped services which is considered a leak. For example, say on the first HTTP request your singleton receives a scoped auth context, on subsequent requests it will be using that same auth context that it got in the first request.

You are correct that this use case is common, and your original solution is how you'd solve it, but you mention that you're taking a performance hit. Could you elaborate on this? I've been running the same setup as you in production at my current company for the past 7 years and haven't had a performance issue that could be traced back to scoped services.

Some questions:

  • Approximately how many scoped services get resolved in a typical request?
  • What injection mode are you using? Classic mode will give you the best performance as it scans class/function dependencies at declaration time and does not have the overhead of a Proxy call.

If you're certain that this is indeed a significant cause of GC churn, then I would recommend that you pass in your auth context via arguments, and use the factory pattern for constructing short-lived services (e.g. ones that use per-scope caching). This is how I've been doing it for new things I've been building, both in JS/TS and in other languages like C#.

from awilix.

steliosrammos avatar steliosrammos commented on June 2, 2024

Thank you for your quick response and proposed solution!

I realise the solution I suggested would cause a leak, it makes sense to drop that idea. What I ended up doing was to use AsyncLocalStorage to create a ReqContextStore. Then I added an Express middleware to add the authContext to that store on each request. That allows me to create a singleton reqContextStore (and keep all the services as singletons) while still having access to the authContext per request.

For more context on my issue, let me also answer your questions:

Approximately how many scoped services get resolved in a typical request?

The way the DI is currently structured, there's about 100 registered scoped objects (Services, UseCases, DomainEventHandlers). A typical requests likely resolves around 1-2 Services and 3-4 UseCases. The issues comes with the DomainEventHandlers. I have a DomainEventDispatcher on which I register handlers for various DomainEvents. Because of the way it's currently implemented, I must manually resolve all the registered handlers on each request, and that causes 10-20 of them to be instantiated. And with each new handlers, there's a little bit more overhead added. I could refactor the DomainEventDispatcher but I was curious to see if there was a way they could all be turned into singletons instead, which I think the above solution achieves.

What injection mode are you using? Classic mode will give you the best performance as it scans class/function dependencies at declaration time and does not have the overhead of a Proxy call.

All the services use the proxied injection mode, while the rest typically use the classic mode. It's good to know the classic mode yields better performance! I'll keep that in mind for the future.

I guess this issue can be closed, if I end up needing the scoped lifetime for anything else, I'll refer back to this!

from awilix.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.