Skip to content

Commit bd45036

Browse files
NO-SNOW: Change crl cleanup task to be a daemon thread (#2656)
1 parent 88456d8 commit bd45036

File tree

2 files changed

+16
-15
lines changed

2 files changed

+16
-15
lines changed

src/snowflake/connector/crl_cache.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import platform
99
import threading
1010
from abc import ABC, abstractmethod
11-
from concurrent.futures import ThreadPoolExecutor
1211
from dataclasses import dataclass
1312
from datetime import datetime, timedelta, timezone
1413
from 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:

test/unit/test_crl_cache.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ def test_cleanup_loop_double_stop_is_safe(cache_factory):
436436
def test_cleanup_loop_double_start_is_safe_and_restarts(
437437
cache_factory, mem_cache_mock, disk_cache_mock
438438
):
439-
"""Test that calling start_periodic_cleanup multiple times creates new executors"""
439+
"""Test that calling start_periodic_cleanup multiple times creates new threads"""
440440
# Set up singleton instances to be cleaned
441441
cache_factory._memory_cache_instance = mem_cache_mock
442442
cache_factory._file_cache_instance = disk_cache_mock

0 commit comments

Comments
 (0)