cachekit 0.11.0__tar.gz → 0.11.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. {cachekit-0.11.0 → cachekit-0.11.1}/Cargo.lock +3 -3
  2. {cachekit-0.11.0 → cachekit-0.11.1}/PKG-INFO +1 -1
  3. {cachekit-0.11.0 → cachekit-0.11.1}/pyproject.toml +1 -1
  4. {cachekit-0.11.0 → cachekit-0.11.1}/rust/Cargo.toml +1 -1
  5. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/__init__.py +1 -1
  6. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/cache_handler.py +1 -1
  7. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/config/singleton.py +20 -3
  8. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/serializers/encryption_wrapper.py +1 -1
  9. {cachekit-0.11.0 → cachekit-0.11.1}/Cargo.toml +0 -0
  10. {cachekit-0.11.0 → cachekit-0.11.1}/LICENSE +0 -0
  11. {cachekit-0.11.0 → cachekit-0.11.1}/README.md +0 -0
  12. {cachekit-0.11.0 → cachekit-0.11.1}/rust/Makefile +0 -0
  13. {cachekit-0.11.0 → cachekit-0.11.1}/rust/README.md +0 -0
  14. {cachekit-0.11.0 → cachekit-0.11.1}/rust/TEST_EXPANSION_SUMMARY.md +0 -0
  15. {cachekit-0.11.0 → cachekit-0.11.1}/rust/src/lib.rs +0 -0
  16. {cachekit-0.11.0 → cachekit-0.11.1}/rust/src/python_bindings.rs +0 -0
  17. {cachekit-0.11.0 → cachekit-0.11.1}/rust/supply-chain/audits.toml +0 -0
  18. {cachekit-0.11.0 → cachekit-0.11.1}/rust/supply-chain/config.toml +0 -0
  19. {cachekit-0.11.0 → cachekit-0.11.1}/rust/supply-chain/imports.lock +0 -0
  20. {cachekit-0.11.0 → cachekit-0.11.1}/rust/tsan_suppressions.txt +0 -0
  21. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/__init__.py +0 -0
  22. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/base.py +0 -0
  23. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/base_config.py +0 -0
  24. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/__init__.py +0 -0
  25. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/backend.py +0 -0
  26. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/client.py +0 -0
  27. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/config.py +0 -0
  28. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/error_handler.py +0 -0
  29. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/session.py +0 -0
  30. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/errors.py +0 -0
  31. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/file/__init__.py +0 -0
  32. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/file/backend.py +0 -0
  33. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/file/config.py +0 -0
  34. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/memcached/__init__.py +0 -0
  35. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/memcached/backend.py +0 -0
  36. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/memcached/config.py +0 -0
  37. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/memcached/error_handler.py +0 -0
  38. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/provider.py +0 -0
  39. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/redis/__init__.py +0 -0
  40. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/redis/backend.py +0 -0
  41. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/redis/client.py +0 -0
  42. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/redis/config.py +0 -0
  43. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/redis/error_handler.py +0 -0
  44. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/backends/redis/provider.py +0 -0
  45. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/config/__init__.py +0 -0
  46. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/config/decorator.py +0 -0
  47. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/config/nested.py +0 -0
  48. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/config/settings.py +0 -0
  49. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/config/validation.py +0 -0
  50. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/decorators/__init__.py +0 -0
  51. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/decorators/intent.py +0 -0
  52. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/decorators/local_wrapper.py +0 -0
  53. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/decorators/main.py +0 -0
  54. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/decorators/orchestrator.py +0 -0
  55. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/decorators/session.py +0 -0
  56. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/decorators/stats_context.py +0 -0
  57. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/decorators/tenant_context.py +0 -0
  58. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/decorators/utils/__init__.py +0 -0
  59. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/decorators/wrapper.py +0 -0
  60. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/di.py +0 -0
  61. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/hash_utils.py +0 -0
  62. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/health.py +0 -0
  63. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/hiredis_compat.py +0 -0
  64. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/imports.py +0 -0
  65. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/invalidation/__init__.py +0 -0
  66. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/invalidation/channel.py +0 -0
  67. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/invalidation/event.py +0 -0
  68. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/invalidation/redis_channel.py +0 -0
  69. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/key_generator.py +0 -0
  70. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/l1_cache.py +0 -0
  71. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/logging.py +0 -0
  72. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/monitoring/__init__.py +0 -0
  73. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/monitoring/correlation_tracking.py +0 -0
  74. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/monitoring/pool_monitor.py +0 -0
  75. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/monitoring/protocols.py +0 -0
  76. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/object_cache.py +0 -0
  77. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/py.typed +0 -0
  78. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/reliability/__init__.py +0 -0
  79. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/reliability/adaptive_timeout.py +0 -0
  80. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/reliability/async_metrics.py +0 -0
  81. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/reliability/circuit_breaker.py +0 -0
  82. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/reliability/error_classification.py +0 -0
  83. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/reliability/load_control.py +0 -0
  84. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/reliability/metrics_collection.py +0 -0
  85. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/reliability/profiles.py +0 -0
  86. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/serializers/__init__.py +0 -0
  87. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/serializers/arrow_serializer.py +0 -0
  88. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/serializers/auto_serializer.py +0 -0
  89. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/serializers/base.py +0 -0
  90. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/serializers/orjson_serializer.py +0 -0
  91. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/serializers/standard_serializer.py +0 -0
  92. {cachekit-0.11.0 → cachekit-0.11.1}/src/cachekit/serializers/wrapper.py +0 -0
@@ -271,7 +271,7 @@ dependencies = [
271
271
 
272
272
  [[package]]
273
273
  name = "cachekit-rs"
274
- version = "0.11.0"
274
+ version = "0.11.1"
275
275
  dependencies = [
276
276
  "cachekit-core",
277
277
  "criterion",
@@ -954,9 +954,9 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
954
954
 
955
955
  [[package]]
956
956
  name = "memmap2"
957
- version = "0.9.10"
957
+ version = "0.9.11"
958
958
  source = "registry+https://github.com/rust-lang/crates.io-index"
959
- checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3"
959
+ checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0"
960
960
  dependencies = [
961
961
  "libc",
962
962
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cachekit
3
- Version: 0.11.0
3
+ Version: 0.11.1
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "cachekit"
7
- version = "0.11.0"
7
+ version = "0.11.1"
8
8
  description = "Production-ready Redis caching for Python with intelligent reliability features and Rust-powered performance"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "cachekit-rs"
3
- version = "0.11.0"
3
+ version = "0.11.1"
4
4
  edition = "2021"
5
5
  authors = ["cachekit Contributors"]
6
6
  description = "High-performance storage engine for caching with compression and encryption"
@@ -68,7 +68,7 @@ Example Usage:
68
68
  ```
69
69
  """
70
70
 
71
- __version__ = "0.11.0"
71
+ __version__ = "0.11.1"
72
72
 
73
73
  from collections.abc import Callable
74
74
  from typing import Any, TypeVar
@@ -308,7 +308,7 @@ class CacheSerializationHandler:
308
308
  deployment_uuid: Optional deployment-specific UUID for single-tenant mode.
309
309
  If not provided, uses env var or persistent file.
310
310
  master_key: Optional master key for encryption (hex-encoded). If not provided,
311
- reads from REDIS_CACHE_MASTER_KEY environment variable.
311
+ reads from CACHEKIT_MASTER_KEY environment variable.
312
312
  enable_integrity_checking: Enable integrity checking (default: True)
313
313
  Uses xxHash3-64 (8 bytes) for all serializers.
314
314
  Set to False for @cache.minimal (speed-first, no checksums)
@@ -1,5 +1,6 @@
1
1
  """Thread-safe singleton pattern for global cachekit settings."""
2
2
 
3
+ import os
3
4
  import threading
4
5
  from typing import Optional
5
6
 
@@ -43,9 +44,25 @@ def get_settings() -> CachekitConfig:
43
44
  """
44
45
  global _settings_instance
45
46
 
46
- # Fast path - return cached instance without lock
47
- if _settings_instance is not None:
48
- return _settings_instance
47
+ # Fast path - snapshot the global once. A concurrent reset_settings() can null _settings_instance
48
+ # at any time, so the unlocked self-heal check below reads the snapshot, never the global, or it
49
+ # could dereference None between the not-None check and the .master_key access.
50
+ instance = _settings_instance
51
+ if instance is not None:
52
+ # Self-heal the keyless-then-key-set ordering trap (#195): if the config was first built
53
+ # before CACHEKIT_MASTER_KEY entered the environment (e.g. an import-time cache decorator
54
+ # evaluated before the app loaded its secrets), it froze master_key=None — encryption would
55
+ # then silently never activate. Re-read once the key appears, so it turns on without an
56
+ # explicit reset_settings(). Idempotent: after the rebuild master_key is set, so this never
57
+ # fires again (no per-call churn once a key is present).
58
+ if instance.master_key is None and os.environ.get("CACHEKIT_MASTER_KEY"):
59
+ with _settings_lock:
60
+ # Re-read the global under the lock: a peer may have rebuilt it (key now set) or
61
+ # reset_settings() may have cleared it (back to None). Rebuild only if still keyless.
62
+ if _settings_instance is None or _settings_instance.master_key is None:
63
+ _settings_instance = CachekitConfig.from_env()
64
+ return _settings_instance
65
+ return instance
49
66
 
50
67
  # Slow path - create instance with lock
51
68
  with _settings_lock:
@@ -128,7 +128,7 @@ class EncryptionWrapper:
128
128
  settings = get_settings()
129
129
  if not settings.master_key:
130
130
  raise EncryptionError(
131
- "Master key required. Set REDIS_CACHE_MASTER_KEY environment variable or pass master_key parameter."
131
+ "Master key required. Set CACHEKIT_MASTER_KEY environment variable or pass master_key parameter."
132
132
  )
133
133
  try:
134
134
  master_key = bytes.fromhex(settings.master_key.get_secret_value())
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes