Coverage for src\zapy\utils\singleton.py: 100%

11 statements  

« prev     ^ index     » next       coverage.py v7.3.4, created at 2023-12-20 14:17 -0500

1from threading import Lock 

2 

3 

4class SingletonMeta(type): 

5 """ 

6 This is a thread-safe implementation of Singleton. 

7 """ 

8 

9 _instances = {} 

10 

11 _lock: Lock = Lock() 

12 """ 

13 We now have a lock object that will be used to synchronize threads during 

14 first access to the Singleton. 

15 """ 

16 

17 def __call__(cls, *args, **kwargs): 

18 """ 

19 Possible changes to the value of the `__init__` argument do not affect 

20 the returned instance. 

21 """ 

22 # Now, imagine that the program has just been launched. Since there's no 

23 # Singleton instance yet, multiple threads can simultaneously pass the 

24 # previous conditional and reach this point almost at the same time. The 

25 # first of them will acquire lock and will proceed further, while the 

26 # rest will wait here. 

27 with cls._lock: 

28 # The first thread to acquire the lock, reaches this conditional, 

29 # goes inside and creates the Singleton instance. Once it leaves the 

30 # lock block, a thread that might have been waiting for the lock 

31 # release may then enter this section. But since the Singleton field 

32 # is already initialized, the thread won't create a new object. 

33 if cls not in cls._instances: 

34 instance = super().__call__(*args, **kwargs) 

35 cls._instances[cls] = instance 

36 return cls._instances[cls]