88import platform
99import threading
1010from abc import ABC , abstractmethod
11- from concurrent .futures import ThreadPoolExecutor
1211from dataclasses import dataclass
1312from datetime import datetime , timedelta , timezone
1413from pathlib import Path
@@ -426,7 +425,7 @@ class CRLCacheFactory:
426425 _instance_lock = threading .RLock ()
427426
428427 # Cleanup management
429- _cleanup_executor : ThreadPoolExecutor | None = None
428+ _cleanup_thread : threading . Thread | None = None
430429 _cleanup_shutdown : threading .Event = threading .Event ()
431430 _cleanup_interval : timedelta | None = None
432431 _atexit_registered : bool = False
@@ -504,17 +503,19 @@ def start_periodic_cleanup(cls, cleanup_interval: timedelta) -> None:
504503 cls .stop_periodic_cleanup ()
505504
506505 cls ._cleanup_interval = cleanup_interval
507- cls ._cleanup_executor = ThreadPoolExecutor (
508- max_workers = 1 , thread_name_prefix = "crl-cache-cleanup"
506+ cls ._cleanup_thread = threading .Thread (
507+ target = cls ._cleanup_loop ,
508+ name = "crl-cache-cleanup" ,
509+ daemon = True , # Make it a daemon thread so it doesn't block program exit
509510 )
510511
511512 # Register atexit handler for graceful shutdown (only once)
512513 if not cls ._atexit_registered :
513514 atexit .register (cls ._atexit_cleanup_handler )
514515 cls ._atexit_registered = True
515516
516- # Submit the cleanup task
517- cls ._cleanup_executor . submit ( cls . _cleanup_loop )
517+ # Start the cleanup thread
518+ cls ._cleanup_thread . start ( )
518519
519520 logger .debug (
520521 f"Scheduled CRL cache cleanup task to run every { cleanup_interval .total_seconds ()} seconds."
@@ -523,29 +524,29 @@ def start_periodic_cleanup(cls, cleanup_interval: timedelta) -> None:
523524 @classmethod
524525 def stop_periodic_cleanup (cls ) -> None :
525526 """Stop the periodic cleanup task."""
526- executor_to_shutdown = None
527+ thread_to_join = None
527528
528529 with cls ._instance_lock :
529- if cls ._cleanup_executor is None or cls ._cleanup_shutdown .is_set ():
530+ if cls ._cleanup_thread is None or cls ._cleanup_shutdown .is_set ():
530531 return
531532
532533 cls ._cleanup_shutdown .set ()
533- executor_to_shutdown = cls ._cleanup_executor
534+ thread_to_join = cls ._cleanup_thread
534535
535- # Shutdown outside of lock to avoid deadlock
536- if executor_to_shutdown is not None :
537- executor_to_shutdown . shutdown ( wait = True )
536+ # Join thread outside of lock to avoid deadlock
537+ if thread_to_join is not None and thread_to_join . is_alive () :
538+ thread_to_join . join ( timeout = 5.0 )
538539
539540 with cls ._instance_lock :
540541 cls ._cleanup_shutdown .clear ()
541- cls ._cleanup_executor = None
542+ cls ._cleanup_thread = None
542543 cls ._cleanup_interval = None
543544
544545 @classmethod
545546 def is_periodic_cleanup_running (cls ) -> bool :
546547 """Check if periodic cleanup task is running."""
547548 with cls ._instance_lock :
548- return cls ._cleanup_executor is not None
549+ return cls ._cleanup_thread is not None and cls . _cleanup_thread . is_alive ()
549550
550551 @classmethod
551552 def _cleanup_loop (cls ) -> None :
0 commit comments