laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 28 forks source link

Contianer scope between instance and singleton (reset resolved instances) #2487

Closed joelharkes closed 3 years ago

joelharkes commented 3 years ago

The container has 2 scopes currently: instance and singleton.

Preferably i would like to see an additional scope. This scope resets (removes resolved instances) when:

now using singleton would mean i'm endlessly reusing the same class now using instance means re-instantiating the same class over and over again, which has its additional warmup cost. and for example, unwanted loss of memory.

joelharkes commented 3 years ago

The dotnet implementation for example makes new child-containers for each context/request and if it cannot be resolved by parent stores the instance in the child container. this way you can easily switch context.

erikdonohoo commented 3 years ago

I want this so badly. We ran into major bugs when using singletons. We run queueing and background jobs using supervisor, those singletons live forever until supervisor is reset. We do background video encoding, and the singleton we made for the encoding lib happens to grab a token for their API during construction that expires, and since the singleton lived forever on supervisor, it was never reset and the tokens eventually expired. To me instance and singleton, neither are truly that useful. What you really want is to get a service once per request/job context, and have the next request/job context reset those instances the next time you ask for them.

joelharkes commented 3 years ago

I want this so badly. We ran into major bugs when using singletons. We run queueing and background jobs using supervisor, those singletons live forever until supervisor is reset. We do background video encoding, and the singleton we made for the encoding lib happens to grab a token for their API during construction that expires, and since the singleton lived forever on supervisor, it was never reset and the tokens eventually expired. To me instance and singleton, neither are truly that useful. What you really want is to get a service once per request/job context, and have the next request/job context reset those instances the next time you ask for them.

By your sound you just need to use the caching driver to store the token with a set expiry date?

themsaid commented 3 years ago

This is done in Laravel Octane. You can also use $container->forgetInstance('service') to reset the instances on certain events of your choice.

joelharkes commented 3 years ago

This is done in Laravel Octane. You can also use $container->forgetInstance('service') to reset the instances on certain events of your choice.

That sounds more like a hack than a solution. You want to define the scope of your instance when you define it, not afterwards have to delete it manually. That's quite a serious antipattern.

The system is missing a 'request' scope

joelharkes commented 3 years ago

It has been implemented with ->scope($interface, $instanceFn).