Skip to content

Conversation

@varonix0
Copy link
Member

@varonix0 varonix0 commented Jan 19, 2026

The SecretsCache was leaking threads because it relied on the Python __del__ method to stop the background cleanup thread, but __del__ is not reliably called by the python garbage collector. Each time a client was created, a new cleanup thread was spawned that would never terminate, causing thread counts to grow without bounds in long running applications or applications that create multiple client instances.

Users can now optionally call client.close() or use the client as a context manager (with InfisicalSDKClient(...) as client:) for instant cleanup, but even without explicit cleanup, threads will now self-terminate when the garbage collector reclaims the cache object. This ensures the SDK no longer leaks threads regardless of how it's used.

Two new dependencies, weakref and atexit, which have been apart of the Python standard library since 2000/2001 respectively. This will continue working even for folks on older Python versions.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 19, 2026

Greptile Summary

Fixed thread leak in SecretsCache by replacing unreliable __del__ cleanup with a multi-layered approach: weakref pattern for automatic thread termination on GC, explicit close() method for manual cleanup, context manager support, and atexit handler for interpreter shutdown.

  • Changed cleanup thread to use weakref.ref(self) to avoid keeping cache alive
  • Replaced boolean flag with threading.Event for cleaner signaling
  • Added _closed flag to prevent operations after cleanup
  • Added global WeakSet registry and atexit handler for shutdown cleanup
  • Client now supports context manager pattern (with InfisicalSDKClient(...) as client:)
  • Fixed docstring typo in get_token() method

Confidence Score: 4/5

  • Safe to merge with one critical race condition that should be addressed
  • The PR successfully fixes the thread leak issue with a well-designed weakref pattern, but there's a subtle race condition in _cleanup_worker_static where the cache could be GC'd between the existence check and cleanup call, potentially causing a crash on a partially destroyed object. The fix is straightforward (wrap cleanup in try/finally).
  • Pay attention to infisical_sdk/util/secrets_cache.py - the race condition in the cleanup worker should be fixed

Important Files Changed

Filename Overview
infisical_sdk/util/secrets_cache.py Thread leak fix using weakref pattern, atexit handler, and explicit close() method - good implementation with minor edge case
infisical_sdk/client.py Added context manager support and close() method to delegate cleanup to cache

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@varonix0 varonix0 requested a review from victorvhs017 January 19, 2026 23:55
Copy link
Contributor

@victorvhs017 victorvhs017 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@varonix0 varonix0 merged commit 840ef0d into main Jan 20, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants