injector
injector copied to clipboard
ThreadLocalScope doesn't clear manually set Keys
Manually bound Key
s end up caching a value you might expect to be thread local with ThreadLocalScope
. The problem is that for manually bound items, a InstanceProvider(to)
is created. Then later ThreadLocalScope
does
provider = InstanceProvider(provider.get(self.injector))
Where provider.get
just returns that to
always. I would have expected something fancier to happen such that thread2 would never see the binding.
TEST_KEY = Key('TEST_KEY')
thread1
injector.binder.bind(TEST_KEY, 'test', threadlocal)
assert(injector.get(TEST_KEY) == 'test')
thread2
assert(injector.get(TEST_KEY) == 'test')
https://github.com/alecthomas/injector/blob/master/injector.py#L442 https://github.com/alecthomas/injector/blob/master/injector.py#L608
Not really sure what the best approach would be. I would have thought that the thread local scope sort of owned the binding created when I did
injector.binder.bind(TEST_KEY, 'test', threadlocal)
I also think ThreadLocalScope
could use a clear/reset method, since if you are using thread pooling, you could leak scopes unless they get cleared.
There's a test case for threadlocal that passes. What's the difference between how the test runs and how you're using it?
Also, I would expect your example to do what it does, right? It's effectively a constant, so it's always going to return the same thing.
I would think that
injector.binder.bind(TEST_KEY, 'test', threadlocal)
Would behave a lot like just setting a thread local variable.
tl_local = threading.local()
# thread1
tl_local.x = 'y'
# thread2
tl_local.x is None
The test is binding a class. That works fine. The problem is when binding a value. InstanceProvider
is treating it like a constant vs a thread local value.
My specific use case is I am setting a user object as a key.
injector.binder.bind(AuthenticatedUser, user_instance, threadlocal)
And I need to make sure that other thread/requests don't ever return that user.