Coverage for app/delivery_fee/utility_meta_classes.py: 82%
22 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-11-27 09:26 +0000
« prev ^ index » next coverage.py v7.4.1, created at 2024-11-27 09:26 +0000
1from threading import Lock
4class ThreadSafeSingletonMeta(type):
5 """
6 This is a thread-safe implementation of Singleton.
7 Source: https://refactoring.guru/design-patterns/singleton/python/example#example-1
8 """
10 _instances = {}
12 _lock: Lock = Lock()
13 """
14 We now have a lock object that will be used to synchronize threads during
15 first access to the Singleton.
16 """
18 def __call__(cls, *args, **kwargs):
19 """
20 Possible changes to the value of the `__init__` argument do not affect
21 the returned instance.
22 """
23 # Now, imagine that the program has just been launched. Since there's no
24 # Singleton instance yet, multiple threads can simultaneously pass the
25 # previous conditional and reach this point almost at the same time. The
26 # first of them will acquire lock and will proceed further, while the
27 # rest will wait here.
28 with cls._lock:
29 # The first thread to acquire the lock, reaches this conditional,
30 # goes inside and creates the Singleton instance. Once it leaves the
31 # lock block, a thread that might have been waiting for the lock
32 # release may then enter this section. But since the Singleton field
33 # is already initialized, the thread won't create a new object.
34 if cls not in cls._instances:
35 instance = super().__call__(*args, **kwargs)
36 cls._instances[cls] = instance
37 return cls._instances[cls]
39 def clear_singleton_instance(cls):
40 """
41 This method is used for testing purposes only.
42 """
43 with cls._lock:
44 if cls in cls._instances:
45 cls._instances.pop(cls)
48class SingletonMeta(type):
49 """
50 The Singleton class can be implemented in different ways in Python. Some
51 possible methods include: base class, decorator, metaclass. We will use the
52 metaclass because it is best suited for this purpose.
53 Source: https://refactoring.guru/design-patterns/singleton/python/example#example-0
54 """
56 _instances = {}
58 def __call__(cls, *args, **kwargs):
59 """
60 Possible changes to the value of the `__init__` argument do not affect
61 the returned instance.
62 """
63 if cls not in cls._instances:
64 instance = super().__call__(*args, **kwargs)
65 cls._instances[cls] = instance
66 return cls._instances[cls]