Skip to content

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_key and invalidate_location_cache
  • Updated cache key generation in read_delivery_locations()
  • Updated cache invalidation in create_delivery_location(), update_delivery_location(), and delete_delivery_location()

Storage Locations (app/api/routes/storage_locations.py)

  • Added imports for generate_cache_key and invalidate_location_cache
  • Updated cache key generation in read_storage_locations()
  • Updated cache invalidation in create_storage_location(), update_storage_location(), and delete_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:

  1. Gets the initial count of delivery locations
  2. Creates a new delivery location
  3. Verifies the new location appears in the updated list immediately
  4. Cleans up by deleting the test location

Cache Invalidation Strategy

The invalidate_location_cache() function implements a comprehensive invalidation strategy:

  1. Specific Entity Invalidation: Invalidates cache for the specific location ID
  2. Entity Type Invalidation: Invalidates all cache entries for the location type
  3. Related Entity Invalidation: Invalidates related location types and general location caches
  4. 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.

  • app/core/cache_utils.py - Standardized cache utilities
  • app/core/redis.py - Redis cache manager implementation
  • app/api/routes/delivery_locations.py - Delivery location endpoints
  • app/api/routes/storage_locations.py - Storage location endpoints
  • app/api/routes/locations.py - General location endpoints
  • test_cache_fix.py - Cache invalidation test script