feat: add Memcached backend with pymemcache HashClient#67
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
- MemcachedBackend implementing BaseBackend protocol (get/set/delete/exists/health_check) - pymemcache HashClient for consistent hashing across multiple servers - TTL clamped to 30-day Memcached maximum (2,592,000 seconds) - MemcachedBackendConfig with pydantic-settings (CACHEKIT_MEMCACHED_ env prefix) - Error classification mapping pymemcache exceptions to BackendErrorType - Lazy import via __getattr__ (pymemcache is optional dependency) - 79 unit/config/critical tests (all mocked — integration tests to follow)
Bug fix: health_check() called self._client.stats() but HashClient has no stats() method — only Client does. Replaced with a benign get() probe. The unit tests never caught this because they mocked everything. This is exactly why integration tests matter. Integration tests (28 total, all against real Memcached): - CRUD round-trip: set/get/delete/exists, overwrite, empty values - TTL expiry: real server-side eviction, negative TTL, 30-day clamp - Key prefix isolation: namespace separation verified - Binary data integrity: null bytes, all-byte-values, 1MB payloads - Concurrent thread safety: 10 threads x 50 ops, mixed read/write/delete - Health check: live server + unreachable server - Decorator integration: @cache.minimal with set_default_backend - Edge cases: 500-key bulk ops, rapid set/delete cycles Threading note: per-thread MemcachedBackend instances used for concurrency tests — pymemcache HashClient pool has known contention issues when shared across many threads simultaneously.
Was missing from BACKEND_CONFIGS parametrization — never added when the memcached backend was created.
- Bump requests>=2.33.0 (CVE-2026-25645) in dev deps with py>=3.10 marker - Ignore pygments GHSA-5239-wwwm-4pmq in pip-audit (no upstream fix) - Validate server port is numeric and in range 1-65535 - Route health_check probe through _prefixed_key() for consistency
- Add error-raising tests for get/set/delete/exists except branches - Add __getattr__ lazy import tests for MemcachedBackend and unknown attr
CI PRs only run tests/critical/ for coverage. Added error paths, health_check failure, TTL clamping, key prefix, error classification, lazy import, and config validation to critical tests.
81507f5 to
03315da
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
health_check()was callingHashClient.stats()which doesn't exist — replaced with benignget()probeTest plan