99
1010class SharedSystemClient :
1111 _identifier_to_system : ClassVar [Dict [str , System ]] = {}
12+ _identifier_to_refcount : ClassVar [Dict [str , int ]] = {}
1213 _identifier : str
1314
1415 def __init__ (
@@ -17,6 +18,9 @@ def __init__(
1718 ) -> None :
1819 self ._identifier = SharedSystemClient ._get_identifier_from_settings (settings )
1920 SharedSystemClient ._create_system_if_not_exists (self ._identifier , settings )
21+ SharedSystemClient ._identifier_to_refcount [self ._identifier ] = (
22+ SharedSystemClient ._identifier_to_refcount .get (self ._identifier , 0 ) + 1
23+ )
2024
2125 @classmethod
2226 def _create_system_if_not_exists (
@@ -25,6 +29,7 @@ def _create_system_if_not_exists(
2529 if identifier not in cls ._identifier_to_system :
2630 new_system = System (settings )
2731 cls ._identifier_to_system [identifier ] = new_system
32+ cls ._identifier_to_refcount [identifier ] = 0
2833
2934 new_system .instance (ProductTelemetryClient )
3035 new_system .instance (ServerAPI )
@@ -83,9 +88,35 @@ def from_system(cls, system: System) -> "SharedSystemClient":
8388 instance = cls (system .settings )
8489 return instance
8590
91+ def __del__ (self ) -> None :
92+ """Clean up System when this client is destroyed."""
93+ if hasattr (self , "_identifier" ):
94+ SharedSystemClient ._decrement_refcount (self ._identifier )
95+
96+ @classmethod
97+ def _decrement_refcount (cls , identifier : str ) -> None :
98+ """Decrement reference count for a System and cleanup if no clients remain."""
99+ if identifier not in cls ._identifier_to_refcount :
100+ return
101+
102+ cls ._identifier_to_refcount [identifier ] -= 1
103+
104+ if cls ._identifier_to_refcount [identifier ] <= 0 :
105+ # since no more client using this system, can stop it and remove from cache
106+ if identifier in cls ._identifier_to_system :
107+ system = cls ._identifier_to_system [identifier ]
108+ system .stop ()
109+ del cls ._identifier_to_system [identifier ]
110+ del cls ._identifier_to_refcount [identifier ]
111+
86112 @staticmethod
87113 def clear_system_cache () -> None :
114+ """Clear the system cache so that new systems can be created for an existing path.
115+ This should only be used for testing purposes."""
116+ for system in SharedSystemClient ._identifier_to_system .values ():
117+ system .stop ()
88118 SharedSystemClient ._identifier_to_system = {}
119+ SharedSystemClient ._identifier_to_refcount = {}
89120
90121 @property
91122 def _system (self ) -> System :
0 commit comments