Cache Invalidation Fix for Location Endpoints
Problem Description
Users were experiencing issues where newly created delivery locations in the admin panel would not appear in the list immediately. The locations were being saved to the database correctly, but the cache was not being invalidated properly, causing stale data to be served until the cache expired or was manually cleared.
Root Cause Analysis
The issue was caused by inconsistent cache key generation and invalidation patterns across location endpoints:
1. Cache Key Mismatch
- Cache keys were generated with complex patterns including user-specific information:
cache_key = f"delivery_locations:user:{user_id}:admin:{is_admin}:skip:{skip}:limit:{limit}:production_run_id:{production_run_id}" - Cache invalidation only used simple prefixes:
cache_manager.invalidate_by_prefix("delivery_locations:") - This created a mismatch where the invalidation pattern didn't match the actual cache keys.
2. Inconsistent Cache Management
- Different location endpoints used different cache key formats
- Manual cache key construction instead of standardized functions
- Simple prefix-based invalidation that didn't account for user-specific cache keys
Solution Implementation
1. Standardized Cache Key Generation
Replaced manual cache key construction with the standardized generate_cache_key() function:
# Before (manual)
cache_key = f"delivery_locations:user:{current_user.id}:admin:{is_admin}:skip:{skip}:limit:{limit}:production_run_id:{production_run_id}"
# After (standardized)
cache_key = generate_cache_key(
entity_type="delivery_location",
user_id=current_user.id,
is_admin=is_admin,
pagination={"skip": skip, "limit": limit},
filters={"production_run_id": production_run_id} if production_run_id else None,
)
2. Comprehensive Cache Invalidation
Replaced simple prefix invalidation with the specialized invalidate_location_cache() function:
# Before (simple prefix)
cache_manager.invalidate_by_prefix("delivery_locations:")
cache_manager.invalidate_by_prefix("storage_locations:")
cache_manager.invalidate_by_prefix("locations:")
# After (comprehensive)
invalidate_location_cache(
location_type="delivery_location",
location_id=location.id,
production_run_id=location.production_run_id,
)
3. Files Modified
Delivery Locations (app/api/routes/delivery_locations.py)
- Added imports for
generate_cache_keyandinvalidate_location_cache - Updated cache key generation in
read_delivery_locations() - Updated cache invalidation in
create_delivery_location(),update_delivery_location(), anddelete_delivery_location()
Storage Locations (app/api/routes/storage_locations.py)
- Added imports for
generate_cache_keyandinvalidate_location_cache - Updated cache key generation in
read_storage_locations() - Updated cache invalidation in
create_storage_location(),update_storage_location(), anddelete_storage_location()
Location Reports (app/api/routes/locations.py)
- Added import for
generate_cache_key - Updated cache key generation in
read_location_reports()
Benefits of the Fix
1. Consistent Cache Keys
- All location endpoints now use the same standardized cache key format
- Cache keys are generated consistently across the application
- Easier to debug and maintain cache-related issues
2. Proper Cache Invalidation
- Cache invalidation patterns now match the actual cache key structure
- Comprehensive invalidation covers all related cache entries
- User-specific cache entries are properly invalidated
3. Immediate Data Visibility
- Newly created locations appear in lists immediately
- No need to wait for cache expiration or manual cache clearing
- Improved user experience in the admin panel
Testing
A test script (test_cache_fix.py) has been created to verify the cache invalidation fix:
python test_cache_fix.py
The test:
- Gets the initial count of delivery locations
- Creates a new delivery location
- Verifies the new location appears in the updated list immediately
- Cleans up by deleting the test location
Cache Invalidation Strategy
The invalidate_location_cache() function implements a comprehensive invalidation strategy:
- Specific Entity Invalidation: Invalidates cache for the specific location ID
- Entity Type Invalidation: Invalidates all cache entries for the location type
- Related Entity Invalidation: Invalidates related location types and general location caches
- Production Run Invalidation: If associated with a production run, invalidates related production run caches
Current Status
This fix has been superseded by the comprehensive Caching System which standardizes cache key formats and invalidation patterns across all entities.
The principles from this fix are now part of the system-wide caching approach.
Related Files
app/core/cache_utils.py- Standardized cache utilitiesapp/core/redis.py- Redis cache manager implementationapp/api/routes/delivery_locations.py- Delivery location endpointsapp/api/routes/storage_locations.py- Storage location endpointsapp/api/routes/locations.py- General location endpointstest_cache_fix.py- Cache invalidation test script