@@ -193,8 +193,10 @@ def _update_cache_from_response(self, ff_response: FeatureFlagsResponse):
193193
194194class FeatureFlagsContextFactory :
195195 """
196- Shares flag values per workspace, independent of telemetry/session lifetime.
197- Also manages a shared ThreadPoolExecutor for all background refresh operations.
196+ Process-wide flag values per workspace and a shared refresh executor.
197+
198+ Both are created lazily and retained until process exit. Session close does
199+ not evict values or shut down the executor, which other readers may still use.
198200 """
199201
200202 _context_map : Dict [tuple , _CacheState ] = {}
@@ -234,14 +236,17 @@ def get_instance(
234236
235237 @classmethod
236238 def remove_instance (cls , host , headers = None ):
237- """Evicts a workspace's values and shuts down the executor if the cache is empty."""
239+ """Explicitly evict workspace values and stop the executor if the cache is empty.
240+
241+ Used for test/reset cleanup, not individual session teardown.
242+ """
238243 with cls ._lock :
239244 headers = {name .lower (): value for name , value in (headers or {}).items ()}
240245 key = _cache_key (host , headers )
241246 if key in cls ._context_map :
242247 cls ._context_map .pop (key , None )
243248
244- # If this was the last active context , clean up the thread pool.
249+ # If no cached workspaces remain , clean up the thread pool.
245250 if not cls ._context_map and cls ._executor is not None :
246251 cls ._executor .shutdown (wait = False )
247252 cls ._executor = None
0 commit comments