Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ThreadSafeSingleton provides None if called from separate thread while an earlier call is still processing. #433

garlandhu opened this issue Mar 23, 2021 · 2 comments


Copy link

Hello, 4.6.0 seems to have created an issue with providers.ThreadSafeSingleton.

If the singleton object to be created has a lengthy init time, and the provider is called a second time while the first one is still being created from a seperate thread, the second call returns None instead of the object.

You can recreate this issue with the example below.

import threading
import unittest
from dependency_injector import providers

class ThingThatTakesLongTimeToInitAndNeedsToBeSingleton:
	def __init__(self):
		self.j = 0
		for i in range(1000000):
			self.j += i

provider_of_annoying_object = providers.ThreadSafeSingleton(

class WorkerThatCanMoveToThreadAndCallProvider:

	def __init__(self, provider):
		self._provider = provider
		self.thing_i_made = 0

	def use_provider(self):
		self.thing_i_made = self._provider()
		# Interestingly, if you add a print statement here, it prints 3 times, not twice.

class TestProvidersInThreads(unittest.TestCase):

	def test_provider_called_in_thread(self):
		worker_1 = WorkerThatCanMoveToThreadAndCallProvider(provider_of_annoying_object)
		thread_1 = threading.Thread(target=worker_1.use_provider)

		worker_2 = WorkerThatCanMoveToThreadAndCallProvider(provider_of_annoying_object)
		thread_2 = threading.Thread(target=worker_2.use_provider)

		self.assertIsInstance(worker_1.thing_i_made, ThingThatTakesLongTimeToInitAndNeedsToBeSingleton)
		self.assertIsInstance(worker_2.thing_i_made, ThingThatTakesLongTimeToInitAndNeedsToBeSingleton)
		self.assertIs(worker_1.thing_i_made, worker_2.thing_i_made)

For versions > 4.6.0, this test fails with:

self.assertIsInstance(worker_2.thing_i_made, ThingThatTakesLongTimeToInitAndNeedsToBeSingleton)
AssertionError: None is not an instance of <class 'tests.providers.test_why_image_interface_dead.ThingThatTakesLongTimeToInitAndNeedsToBeSingleton'>
Copy link

rmk135 commented Mar 23, 2021

Hi @garlandhu,

Thanks for reporting the issue. I'm sorry to hear that error was introduced in 4.6. I'll work on a fix ASAP.

@rmk135 rmk135 self-assigned this Mar 23, 2021
@rmk135 rmk135 added the bug label Mar 23, 2021
Copy link

rmk135 commented Mar 24, 2021

Fixed in version 4.31.1. @garlandhu thanks again for reporting the issue.

@rmk135 rmk135 closed this as completed Mar 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

No branches or pull requests

2 participants