You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reliability: removed cachekit.reliability.create_decorator_config and, from cachekit.reliability.profiles, get_decorator_kwargs, minimal_reliability_decorator, balanced_reliability_decorator and full_reliability_decorator. Their output raised TypeError when passed to @cache, so no working call is lost. cachekit.decorators.wrapper.create_cache_wrapper no longer accepts undeclared keyword arguments; it raises TypeError instead of ignoring them.
decorators:FeatureOrchestrator (exported from cachekit.decorators.__all__) no longer defines generate_correlation_id, create_correlation_id, set_correlation_id, clear_correlation_id, start_request, end_request, or the correlation_tracker property. FeatureOrchestrator.handle_cache_error no longer accepts a correlation_id keyword argument. An explicit caller passing correlation_id= now flows it through **extra_context, and its log record is unchanged. The decorator's own *_failed error records no longer carry a correlation_id key; that value was a per-call UUID, or None, and nothing read it. src/cachekit/monitoring/correlation_tracking.py (CorrelationTracker, LoggerIntegratedTracker, module-level generate_correlation_id/set_correlation_id/get_correlation_id/clear_correlation_id/correlation_context) is removed entirely.
metrics:AsyncMetricsCollector.record_cache_operation() and FeatureOrchestrator.record_cache_operation() no longer accept hit. Callers that pass it now raise TypeError. FeatureOrchestrator.record_success() no longer emits a metrics record.
config: presets apply the canonical default TTLs; drop CACHEKIT_DEFAULT_TTL (LAB-4641) (#318)
intent: .secure rejects integrity_checking=False on both paths (LAB-3970) (#359)
interop: Existing deployments that use ns or nsapi as an interop namespace on Redis, Memcached or File backends worked before this change and must now rename the namespace. Renaming means a full cache miss for that namespace.
backends: if your deployment used cachekit under more than one tenant (a call with no tenant set counts as default), purge the Redis entries that earlier releases wrote. In earlier releases a decorated function that resolved Redis from the environment (CACHEKIT_REDIS_URL, REDIS_URL or the localhost default), or a backend taken from RedisBackendProvider.get_backend(), stayed bound to the tenant current when that backend was first obtained, so every tenant's L2 writes through it landed under that one tenant's t:<tenant>: prefix. That tenant keeps reading those entries as its own after the upgrade, and some hold another tenant's value. Entries written with ttl=None, or kept alive by refresh_ttl_on_get=True, never expire, and a no-argument invalidate_cache() reaches only those the calling tenant has read in that process since it started, because no key registry recorded them. After the last process running an earlier release has stopped, delete every t:* key in each database cachekit uses. Run this with the Python that cachekit is installed in, since it uses cachekit's redis-py dependency; it prints 0 keys left when it is done: python -c 'import itertools, sys, redis; r = redis.Redis.from_url(sys.argv[1]); keys = r.scan_iter(match=sys.argv[2], count=1000); [r.unlink(*b) for b in iter(lambda: list(itertools.islice(keys, 1000)), [])]; print(sum(1 for _ in r.scan_iter(match=sys.argv[2], count=1000)), "keys left")' '<redis-url>' 't:*'. Do not use a redis-cli --scan pipeline: a key set through key= can contain a newline or a NUL byte, which the pipeline turns into names that match nothing, so the key survives and the pipeline still exits 0. Run FLUSHDB instead only if that database is dedicated to cachekit. Then restart every process, because L1 keeps any entry a process read before the purge for up to the function's ttl (300 s with ttl=None), and expect a cold cache. On a shared database t:* also matches any other application's keys that start with t:, so run the same command with 't:<tenant>:*' in place of 't:*' for default and for each tenant you have set, the tenant percent-encoded with urllib.parse.quote(tenant, safe=''), an int or UUID tenant as its str() first (tenant org:123 is 't:org%3A123:*'). A deployment that only ever used one tenant is unaffected. RedisBackendProvider.get_backend() no longer binds its backend to one tenant: the backend follows tenant_context on every operation and falls back to the tenant current at the get_backend() call only when the calling context has none; for a backend bound to one tenant, construct cachekit.backends.redis.provider.PerRequestRedisBackend(client, tenant) directly, with client a redis.Redis. A no-argument invalidate_cache() on the Redis backend now deletes only the calling tenant's L2 entries. Set tenant_context only to a str, bytes, int or uuid.UUID: the Redis backend checks each operation's tenant and raises TypeError for any other type, including a bool, an IntEnum member and a bytearray, so convert an IntEnum member with int() and a bytearray with bytes() first. int and UUID tenants now work, keyed by their str() form (42 and "42" share t:42:), which no earlier release did.
backends: the decorator namespace "ck" and any "ck:*" namespace are now reserved for cachekit's internal keys and raise ConfigurationError at decoration time. Rename any function cached under namespace="ck" or a "ck:" prefix before upgrading.
decorators: configure the live circuit breaker from @cache(circuit_breaker=...) (LAB-5340) (#340)
decorators: refuse encryption with backend=None — L1-only held plaintext (LAB-4665) (#322)
logging:cachekit.logging.JsonFormatter is removed; importing it now raises ImportError. StructuredLogger.circuit_breaker_state_change and StructuredLogger.set_correlation_id are removed and now raise AttributeError. No deprecation aliases. Use set_trace_id / clear_trace_id (or cachekit.monitoring.correlation_tracking) for request correlation, and your own logging.Formatter subclass for JSON output.
reliability: cachekit.reliability.create_optimized_decorator_config is renamed to cachekit.reliability.create_decorator_config. Update imports; no alias is provided. cachekit.hash_utils.fast_hash is renamed to blake3_hash (module-internal, never exported from the package).
keys: cache keys for any serializer other than the default change identity on upgrade — no configuration change is required to be affected. A deployment using serializer="auto", "orjson", "arrow", or any serializer passed as an instance was writing :1s keys and will now write :1a, :1o, :1w or an x-prefixed code. That function's entire working set recomputes once at deploy, so plan a cold cache or roll out behind existing warm-up / stampede controls. Deployments on the default serializer are unaffected: their keys were already :1s and stay :1s. Orphaned entries are also a retention question, not only a hit-rate one: once the key changes, invalidate_cache() computes the new key and can no longer reach the old copy, so a deletion for erasure, consent withdrawal or permission revocation reports success while the pre-upgrade entry survives to its TTL — or indefinitely where ttl=None. Flush the affected namespaces on upgrade if you cache personal data rather than relying on expiry.
config: CachekitConfig drops retry_on_timeout, max_retries, retry_delay_ms, early_refresh_ratio, enable_corruption_detection and max_key_size, and no longer reads CACHEKIT_RETRY_ON_TIMEOUT, CACHEKIT_MAX_RETRIES, CACHEKIT_RETRY_DELAY_MS, CACHEKIT_EARLY_REFRESH_RATIO, CACHEKIT_ENABLE_CORRUPTION_DETECTION or CACHEKIT_MAX_KEY_SIZE. None of them changed behaviour. Passing one to CachekitConfig(...) now raises ValidationError; CachekitConfig ignores a still-exported env var, so startup is unaffected. CachekitIOBackendConfig declares its own max_retries under the same prefix and still parses CACHEKIT_MAX_RETRIES; this release does not change it. Integrity checking is set per decorator (integrity_checking=), refresh-ahead timing by L1CacheConfig.swr_threshold_ratio, and Memcached retries by MemcachedBackendConfig.retry_attempts.
decorators:CachekitIOBackend(...) configuration errors (missing, empty or whitespace-containing API key; invalid API URL) now raise cachekit.config.ConfigurationError at construction instead of ValueError or pydantic ValidationError, so code catching ValueError there must catch ConfigurationError. @cache.io(backend=...) and @cache.io(config=...) now raise ConfigurationError instead of silently ignoring the argument. Under set_default_backend(), @cache(config=...) now uses the backend inside config= instead of the module default. cachekit.backends.cachekitio.client.get_sync_http_client() is replaced by lease_sync_http_client(), which returns a SyncClientLease: hold the lease for as long as its .client is used, because the client is closed when the lease is dropped.
encryption: single-tenant tenant_id defaults to "default", not a deployment UUID (LAB-4666) (#321)