# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.5.0] - 2026-03-31
### Fixed
- **Content-type pattern matching used substring instead of exact match** — `"pdf"` in exclusion list would match any MIME type containing "pdf". Now uses exact match with optional parameter suffix (e.g., `application/json; charset=utf-8` matches pattern `application/json`).
- **`force_cache_content_types` doc claimed "regardless of size"** — size limits always applied. Fixed doc to accurately describe behavior: bypasses content-type exclusions only.
- **`unsafe impl Sync for SyncBoxBody` safety comment was incorrect** — claimed "single-threaded" context which is wrong for Tower. Updated with correct safety justification.
- **README documented non-existent `admin_router()` and `AdminConfig::builder()` API** — updated to match actual `AdminConfig::new().with_*()` API.
- **README referenced non-existent examples and `middleware` feature flag** — updated to list actual examples.
- **README installation instructions referenced version `"0.3"`** — updated to `"0.5"`.
- **`._*` macOS resource fork files were included in crates.io package** — added to `exclude` in Cargo.toml and `.gitignore`.
- **CHANGELOG footer links missing for v0.4.0–v0.4.3**.
### Changed
- `StreamingDecision::StreamThrough` is now `#[doc(hidden)]` (reserved for future implementation).
- Bumped version to 0.5.0 due to content-type matching behavior change (may affect users relying on substring matching).
## [0.4.3] - 2025-11-10
### Removed
- **Unused dependencies identified by `cargo-udeps`**:
- Removed `serde_bytes` from main dependencies (never used in codebase)
- Removed `hyper` from dev-dependencies (never used in tests/benches/examples)
- Reduces dependency count and compilation time
- No functional changes - all 137 tests passing
### Note
- Dev dependencies `axum`, `redis`, and `tracing-subscriber` flagged by `cargo-udeps` are false positives - they are used in examples and tests
## [0.4.2] - 2025-11-10
### Fixed
- **Removed unused dependency**: Removed `sync_wrapper` crate that was added in v0.4.1 but not used
- Reduces dependency bloat and compilation time
- No functional changes - implementation uses manual `unsafe impl Sync` instead
- Still uses existing `pin_project_lite` for safe pinning
## [0.4.1] - 2025-11-10
### Fixed
- **Axum compatibility**: Fixed `Sync` trait bound issue with response bodies
- Implemented custom `SyncBoxBody` type that wraps `BoxBody` and manually implements `Sync`
- Uses `pin_project_lite` for safe pinning and `HttpBody` trait delegation
- Uses same pattern as Axum's own `Body` type (`unsafe impl Sync`)
- Resolves compilation errors when using the cache layer with Axum routers
- Zero-cost abstraction - same performance as underlying `BoxBody`
- Updated `CacheEntry::into_response()` to return `Response<SyncBoxBody>`
- All 137 tests passing with new body type
### Changed
- Response body type now implements both `HttpBody` and `Sync` for Axum compatibility
- Examples updated to demonstrate Axum integration patterns
- No new dependencies added - uses existing `pin_project_lite`
## [0.4.0] - 2025-11-10
### Added
#### Chunk Caching for Large Files
- **Memory-efficient range request handling**: Chunk-based caching system for large files
- New `chunks` module with `ChunkCache` and `ChunkedEntry` types
- Automatic file splitting into fixed-size chunks (default: 1MB)
- Efficient range request serving from chunk cache
- `ChunkMetadata` for storing HTTP metadata separately from chunks
- Configurable via `StreamingPolicy::enable_chunk_cache`
- Per-chunk storage and retrieval for minimal memory footprint
- Support for partial file caching (only cache accessed ranges)
- Coverage tracking to monitor chunk cache completeness
- Integrated with `CacheLayer` and `CacheService`
- Automatic 206 Partial Content response generation
- Compatible with video streaming and large file downloads
- 40+ comprehensive chunk caching tests
- Production example: `chunk_cache_demo`
#### BB8 Connection Pooling for Memcached
- **Production-grade connection management**: BB8 async connection pooling
- `MemcachedBackend::builder()` with pooling support
- Configurable pool size (min/max connections)
- Connection timeout and retry logic
- Health checks and automatic reconnection
- Pool state monitoring (connections, idle, etc.)
- Graceful shutdown and connection cleanup
- Async-safe with tokio integration
- Production example: `memcached_production`
#### True Streaming Pass-Through (Zero-Copy)
- **BoxBody architecture**: Complete replacement of `Full<Bytes>` with `BoxBody<Bytes, BoxError>`
- Eliminates unnecessary buffering for large responses
- Zero-copy streaming for excluded content types
- Preserves `Content-Length` headers during streaming
- Memory efficient handling of multi-GB responses
- Full backward compatibility with existing middleware
#### HTTP Range Request Support
- **RFC 7233 compliant range handling**: Proper support for partial content requests
- New `range` module with `parse_range_header()` utilities
- `RangeRequest` type for parsing "bytes=start-end" specifications
- `RangeHandling` policy enum (PassThrough/CacheFullServeRanges/CacheChunks)
- Automatic detection of 206 Partial Content responses
- Configurable behavior via `StreamingPolicy::range_handling`
- Content-Range header generation and parsing
- 15+ comprehensive range request tests
#### Memcached Backend
- **High-performance distributed caching**: Production-ready Memcached support
- Async `MemcachedBackend` implementation via `async-memcached`
- Namespace support for multi-tenant deployments
- TTL and stale-while-revalidate handling
- Custom serialization for HTTP types (StatusCode, Version, Bytes)
- Connection pooling with Arc<Mutex<Client>>
- Optional feature flag: `memcached-backend`
- Compatible with memcached protocol 1.6+
#### Enhanced Observability
- **Streaming-specific metrics**: Better visibility into cache behavior
- `tower_http_cache.streaming_passthrough` counter
- `tower_http_cache.range_request_passthrough` counter
- Detailed tracing logs with size and content-type info
- Body size histograms for performance analysis
#### Smart Streaming & Large File Handling
- **Intelligent body size detection**: Prevent large files from overwhelming cache
- `StreamingPolicy` for configurable streaming behavior
- Early detection via `Content-Length` header and `size_hint()`
- Content-Type based filtering (PDFs, videos, archives excluded by default)
- Configurable `max_cacheable_size` (default: 1MB)
- Wildcard content-type matching (e.g., `video/*`, `audio/*`)
- Force-cache lists for critical API responses
- Multi-tier size protection (large entries excluded from L1)
- 20+ unit tests with 100% branch coverage
#### Multi-Tier Size Protection
- **max_l1_entry_size**: Prevent large entries from polluting fast L1 cache
- Configurable size limit for L1 promotion (default: 256KB)
- Automatic size checking during write-through and promotion
- Large entries stored only in L2 for capacity efficiency
- Metrics tracking for skipped L1 writes and promotions
- Zero performance impact on small entries
### Changed
- **BREAKING**: `CacheService` now returns `Response<BoxBody<Bytes, BoxError>>` instead of `Response<Full<Bytes>>`
- This enables true streaming but requires downstream services to handle `BoxBody`
- Migration: Use `.map_err(Into::into).boxed()` on bodies if needed
- Most Tower middleware is compatible without changes
- **BREAKING**: Added `Sync` bound to `ResBody` in Service implementation
- Required for BoxBody's Send + Sync + 'static constraint
- Should not affect most use cases
- `CacheEntry` now has conditional Serde derives with custom serializers for HTTP types
- `StreamingPolicy` now includes `range_handling` field (defaults to `PassThrough`)
- Range requests pass through by default without caching
- Streaming policy enabled by default (can be disabled)
- Size limits now apply consistently to all content types (including forced-cache types)
### Performance
- **Chunk caching**: 90% memory reduction for large file workloads
- Only cache accessed chunks (not entire file)
- Instant seeking for video streaming (no re-download)
- Range requests served directly from memory
- Configurable chunk size for optimal throughput
- **Zero-copy streaming**: Eliminated buffering for excluded content types
- **BB8 connection pooling**: 10x throughput improvement for Memcached
- Reduced connection overhead
- Concurrent request handling
- Automatic connection reuse
- Memory efficient: Handles multi-GB responses without collecting into memory
- Eliminates memory exhaustion from large file responses
- Prevents cache pollution from 5-20MB files
- Protects L1 cache from unnecessary large entry storage
- < 1% overhead on streaming decision path
### Fixed
- Conditional compilation for `extract_size_info` import (tracing feature)
- BoxBody compatibility with Tower service ecosystem
- Proper Sync bounds for concurrent body handling
## [0.3.0] - 2025-11-10
### Added
#### Cache Tags & Invalidation Groups
- **Tag-based cache invalidation**: Group related cache entries with tags and invalidate them together
- `TagPolicy` for configuring tag behavior
- `TagIndex` for efficient bidirectional tag→key and key→tag lookups
- `invalidate_by_tag()` and `invalidate_by_tags()` methods
- Automatic cleanup of orphaned tag entries
- Thread-safe using `DashMap` for lock-free concurrent access
- Integrated with both in-memory and Redis backends
- 17 comprehensive unit tests
#### Multi-Tier Caching
- **L1 + L2 hybrid backend**: Combine fast in-memory cache with larger distributed storage
- `MultiTierBackend<L1, L2>` generic over any two `CacheBackend` implementations
- Automatic promotion from L2→L1 based on access patterns
- Configurable `PromotionStrategy` (HitCount, HitRate)
- Per-key access tracking with atomic operations
- Write-through and write-back modes
- Graceful tier failure handling
- Tier-specific metrics and observability
- < 2% performance overhead
- 7 integration tests
#### ML-Ready Structured Logging
- **Request correlation and ML training data**: Comprehensive structured logging for analytics
- `RequestId` type for request correlation (following X-Request-ID header)
- `MLLoggingConfig` for configurable sampling, key hashing, and privacy controls
- Rich JSON event format with 15+ metadata fields
- SHA-256 key hashing option for privacy compliance
- Integration with `tracing` crate for structured output
- Cost and complexity tracking for ML model training
- Configurable sampling rate to reduce overhead
- 15 unit tests
#### Admin API & Observability
- **REST API for cache introspection**: Production-ready management endpoints
- 7 REST endpoints for cache management:
- `GET /health` - Health check
- `GET /stats` - Overall statistics
- `GET /hot-keys` - Most accessed keys
- `GET /tags` - List all tags
- `POST /invalidate` - Invalidate by key or tag
- `GET /keys` - List cached keys (planned)
- `GET /key/:key` - Inspect specific key (planned)
- Token-based authentication (Bearer token)
- Real-time statistics collection
- Hot keys tracking with configurable limits
- JSON response format for all endpoints
- Optional feature flag: `admin-api`
- 19 unit tests
### Changed
- Enhanced `CachePolicy` with `tag_policy`, `ml_logging`, and `tag_extractor` fields
- Updated `CacheEntry` to include optional `tags` field
- Extended `CacheBackend` trait with default implementations for tag operations
- Integrated tag support into `InMemoryBackend`
### Dependencies
- Added `uuid` 1.0 with v4 and serde features
- Added `sha2` 0.10 for key hashing
- Added `hex` 0.4 for hash encoding
- Added `chrono` 0.4 for timestamp handling
- Added optional `axum` 0.8 for admin API (behind `admin-api` feature)
- Added optional `governor` 0.6 for rate limiting (behind `admin-api` feature)
### Performance
- Tag indexing: < 1% overhead on cache set operations
- Multi-tier: < 2% total overhead (L1 hot path unchanged)
- ML logging: < 100µs per event with sampling
- Request ID extraction: Negligible (simple header lookup)
### Non-Breaking Changes
All v0.3.0 features are opt-in and backward compatible:
- Default behavior unchanged
- No breaking API changes
- All features disabled by default and require explicit configuration
## [0.2.0] - 2025-11-10
### Added
- **Auto-refresh functionality**: Proactively refreshes frequently-accessed cache entries before they expire
- Lock-free frequency tracking using `AtomicU64` and `DashMap` for minimal performance overhead (< 1%)
- Configurable hit rate thresholds with sliding time windows
- Background task management with graceful shutdown via `Drop`
- Concurrency control using semaphore-based limits
- Request reconstruction from stored metadata
- Full observability support with metrics and tracing
- Comprehensive test coverage with 22 new tests
- `AutoRefreshConfig` for fine-grained configuration
- `init_auto_refresh()` method to enable proactive cache warming
- Added tokio features: `rt`, `time`, `macros` for background task support
### Changed
- Enhanced `CacheLayer` with auto-refresh capabilities
- Enhanced `CacheService` to track cache hits for frequency analysis
- Non-breaking change: auto-refresh is disabled by default and requires explicit configuration
## [0.1.2] - 2025-11-09
### Fixed
- Added `Clone` implementation to `CacheService` to resolve compatibility issues with Axum's `Router::layer` API
## [0.1.1] - 2025-11-09
### Fixed
- Corrected repository URL in Cargo.toml to point to `sadco-io/tower-http-cache`
## [0.1.0] - 2025-11-09
### Added
- Initial release of `tower-http-cache`
- Drop-in `CacheLayer` for Tower services
- Stampede protection with request deduplication
- Flexible TTL configuration (positive/negative TTL, refresh-before-expiry)
- Stale-while-revalidate support
- Pluggable storage backends:
- In-memory backend powered by Moka
- Redis backend with async pooling (optional `redis-backend` feature)
- Policy controls:
- Min/max body size limits
- Cache-Control header respect/override
- Custom method and status code filters
- Header allowlisting
- Custom cache key extraction
- Optional observability:
- Metrics counters via `metrics` crate (optional `metrics` feature)
- Tracing spans (optional `tracing` feature)
- Optional gzip compression (optional `compression` feature)
- Comprehensive test suite
- Benchmark suite with Criterion
- Examples for Axum and Redis integration
[Unreleased]: https://github.com/sadco-io/tower-http-cache/compare/v0.5.0...HEAD
[0.5.0]: https://github.com/sadco-io/tower-http-cache/compare/v0.4.3...v0.5.0
[0.4.3]: https://github.com/sadco-io/tower-http-cache/compare/v0.4.2...v0.4.3
[0.4.2]: https://github.com/sadco-io/tower-http-cache/compare/v0.4.1...v0.4.2
[0.4.1]: https://github.com/sadco-io/tower-http-cache/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/sadco-io/tower-http-cache/compare/v0.3.0...v0.4.0
[0.3.0]: https://github.com/sadco-io/tower-http-cache/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/sadco-io/tower-http-cache/compare/v0.1.2...v0.2.0
[0.1.2]: https://github.com/sadco-io/tower-http-cache/compare/v0.1.1...v0.1.2
[0.1.1]: https://github.com/sadco-io/tower-http-cache/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/sadco-io/tower-http-cache/releases/tag/v0.1.0