Loading...
Automatically clears relevant Redis cache keys when data model files are modified
{
"hookConfig": {
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/redis-cache-invalidator.sh",
"matchers": [
"write",
"edit"
]
}
}
},
"scriptContent": "#!/bin/bash\n\n# Read the tool input from stdin\nINPUT=$(cat)\nTOOL_NAME=$(echo \"$INPUT\" | jq -r '.tool_name')\nFILE_PATH=$(echo \"$INPUT\" | jq -r '.tool_input.file_path // .tool_input.path // \"\"')\n\nif [ -z \"$FILE_PATH\" ]; then\n exit 0\nfi\n\necho \"đ Redis Cache Invalidator - Analyzing file changes...\"\necho \"đ File: $FILE_PATH\"\n\n# Check if this is a model or data file that should trigger cache invalidation\nif [[ \"$FILE_PATH\" == *models/*.js ]] || [[ \"$FILE_PATH\" == *models/*.py ]] || [[ \"$FILE_PATH\" == *models/*.ts ]] || [[ \"$FILE_PATH\" == *schemas/*.* ]] || [[ \"$FILE_PATH\" == *entities/*.* ]]; then\n \n MODEL_NAME=$(basename \"${FILE_PATH%.*}\")\n echo \"đ Model detected: $MODEL_NAME\"\n \n # Check if Redis CLI is available\n if ! command -v redis-cli >/dev/null 2>&1; then\n echo \"â ī¸ redis-cli not found - please install Redis CLI tools\"\n echo \"đĄ Install with: apt-get install redis-tools (Ubuntu) or brew install redis (macOS)\"\n exit 0\n fi\n \n # Test Redis connection\n if ! redis-cli ping >/dev/null 2>&1; then\n echo \"â ī¸ Redis server not accessible - skipping cache invalidation\"\n echo \"đĄ Ensure Redis server is running and accessible\"\n exit 0\n fi\n \n echo \"đ Scanning for cache keys related to: $MODEL_NAME\"\n \n # Find cache keys related to this model\n CACHE_KEYS=$(redis-cli --scan --pattern \"*${MODEL_NAME}*\" 2>/dev/null)\n \n if [ -n \"$CACHE_KEYS\" ]; then\n KEY_COUNT=$(echo \"$CACHE_KEYS\" | wc -l)\n echo \"đī¸ Found $KEY_COUNT cache keys to invalidate:\"\n \n # Show first few keys for confirmation\n echo \"$CACHE_KEYS\" | head -5 | while read -r key; do\n echo \" âĸ $key\"\n done\n \n if [ \"$KEY_COUNT\" -gt 5 ]; then\n echo \" ... and $((KEY_COUNT - 5)) more keys\"\n fi\n \n # Delete the keys\n echo \"$CACHE_KEYS\" | xargs -r redis-cli DEL >/dev/null 2>&1\n echo \"â
Invalidated $KEY_COUNT cache keys for model: $MODEL_NAME\"\n else\n echo \"âšī¸ No cache keys found for model: $MODEL_NAME\"\n fi\n \n # Additional patterns to check\n echo \"đ Checking additional cache patterns...\"\n \n # Check for API route caches\n API_KEYS=$(redis-cli --scan --pattern \"api:*${MODEL_NAME}*\" 2>/dev/null)\n if [ -n \"$API_KEYS\" ]; then\n API_COUNT=$(echo \"$API_KEYS\" | wc -l)\n echo \"$API_KEYS\" | xargs -r redis-cli DEL >/dev/null 2>&1\n echo \"â
Invalidated $API_COUNT API cache keys\"\n fi\n \n # Check for query result caches\n QUERY_KEYS=$(redis-cli --scan --pattern \"query:*${MODEL_NAME}*\" 2>/dev/null)\n if [ -n \"$QUERY_KEYS\" ]; then\n QUERY_COUNT=$(echo \"$QUERY_KEYS\" | wc -l)\n echo \"$QUERY_KEYS\" | xargs -r redis-cli DEL >/dev/null 2>&1\n echo \"â
Invalidated $QUERY_COUNT query cache keys\"\n fi\n \n # Check current Redis stats\n echo \"\"\n echo \"đ Redis Cache Statistics:\"\n TOTAL_KEYS=$(redis-cli DBSIZE 2>/dev/null || echo \"unknown\")\n MEMORY_USAGE=$(redis-cli INFO memory 2>/dev/null | grep used_memory_human | cut -d: -f2 | tr -d '\\r' || echo \"unknown\")\n echo \" âĸ Total keys: $TOTAL_KEYS\"\n echo \" âĸ Memory usage: $MEMORY_USAGE\"\n \n echo \"\"\n echo \"đĄ Cache Invalidation Tips:\"\n echo \" âĸ Use consistent cache key naming patterns\"\n echo \" âĸ Consider cache TTL for automatic expiration\"\n echo \" âĸ Monitor cache hit/miss ratios\"\n echo \" âĸ Use Redis keyspace notifications for advanced invalidation\"\n \n echo \"\"\n echo \"đ¯ Cache invalidation complete!\"\n \nelif [[ \"$FILE_PATH\" == *config/*.* ]] || [[ \"$FILE_PATH\" == *.env ]]; then\n echo \"âī¸ Configuration file detected - consider full cache flush if needed\"\n echo \"đĄ Run 'redis-cli FLUSHDB' manually if configuration affects cached data\"\n \nelse\n echo \"âšī¸ File does not require cache invalidation: $FILE_PATH\"\nfi\n\nexit 0"
}.claude/hooks/~/.claude/hooks/{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/redis-cache-invalidator.sh",
"matchers": [
"write",
"edit"
]
}
}
}#!/bin/bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
echo "đ Redis Cache Invalidator - Analyzing file changes..."
echo "đ File: $FILE_PATH"
# Check if this is a model or data file that should trigger cache invalidation
if [[ "$FILE_PATH" == *models/*.js ]] || [[ "$FILE_PATH" == *models/*.py ]] || [[ "$FILE_PATH" == *models/*.ts ]] || [[ "$FILE_PATH" == *schemas/*.* ]] || [[ "$FILE_PATH" == *entities/*.* ]]; then
MODEL_NAME=$(basename "${FILE_PATH%.*}")
echo "đ Model detected: $MODEL_NAME"
# Check if Redis CLI is available
if ! command -v redis-cli >/dev/null 2>&1; then
echo "â ī¸ redis-cli not found - please install Redis CLI tools"
echo "đĄ Install with: apt-get install redis-tools (Ubuntu) or brew install redis (macOS)"
exit 0
fi
# Test Redis connection
if ! redis-cli ping >/dev/null 2>&1; then
echo "â ī¸ Redis server not accessible - skipping cache invalidation"
echo "đĄ Ensure Redis server is running and accessible"
exit 0
fi
echo "đ Scanning for cache keys related to: $MODEL_NAME"
# Find cache keys related to this model
CACHE_KEYS=$(redis-cli --scan --pattern "*${MODEL_NAME}*" 2>/dev/null)
if [ -n "$CACHE_KEYS" ]; then
KEY_COUNT=$(echo "$CACHE_KEYS" | wc -l)
echo "đī¸ Found $KEY_COUNT cache keys to invalidate:"
# Show first few keys for confirmation
echo "$CACHE_KEYS" | head -5 | while read -r key; do
echo " âĸ $key"
done
if [ "$KEY_COUNT" -gt 5 ]; then
echo " ... and $((KEY_COUNT - 5)) more keys"
fi
# Delete the keys
echo "$CACHE_KEYS" | xargs -r redis-cli DEL >/dev/null 2>&1
echo "â
Invalidated $KEY_COUNT cache keys for model: $MODEL_NAME"
else
echo "âšī¸ No cache keys found for model: $MODEL_NAME"
fi
# Additional patterns to check
echo "đ Checking additional cache patterns..."
# Check for API route caches
API_KEYS=$(redis-cli --scan --pattern "api:*${MODEL_NAME}*" 2>/dev/null)
if [ -n "$API_KEYS" ]; then
API_COUNT=$(echo "$API_KEYS" | wc -l)
echo "$API_KEYS" | xargs -r redis-cli DEL >/dev/null 2>&1
echo "â
Invalidated $API_COUNT API cache keys"
fi
# Check for query result caches
QUERY_KEYS=$(redis-cli --scan --pattern "query:*${MODEL_NAME}*" 2>/dev/null)
if [ -n "$QUERY_KEYS" ]; then
QUERY_COUNT=$(echo "$QUERY_KEYS" | wc -l)
echo "$QUERY_KEYS" | xargs -r redis-cli DEL >/dev/null 2>&1
echo "â
Invalidated $QUERY_COUNT query cache keys"
fi
# Check current Redis stats
echo ""
echo "đ Redis Cache Statistics:"
TOTAL_KEYS=$(redis-cli DBSIZE 2>/dev/null || echo "unknown")
MEMORY_USAGE=$(redis-cli INFO memory 2>/dev/null | grep used_memory_human | cut -d: -f2 | tr -d '\r' || echo "unknown")
echo " âĸ Total keys: $TOTAL_KEYS"
echo " âĸ Memory usage: $MEMORY_USAGE"
echo ""
echo "đĄ Cache Invalidation Tips:"
echo " âĸ Use consistent cache key naming patterns"
echo " âĸ Consider cache TTL for automatic expiration"
echo " âĸ Monitor cache hit/miss ratios"
echo " âĸ Use Redis keyspace notifications for advanced invalidation"
echo ""
echo "đ¯ Cache invalidation complete!"
elif [[ "$FILE_PATH" == *config/*.* ]] || [[ "$FILE_PATH" == *.env ]]; then
echo "âī¸ Configuration file detected - consider full cache flush if needed"
echo "đĄ Run 'redis-cli FLUSHDB' manually if configuration affects cached data"
else
echo "âšī¸ File does not require cache invalidation: $FILE_PATH"
fi
exit 0Hook skips invalidation with redis-cli not found warning
Install Redis CLI tools using 'apt-get install redis-tools' (Ubuntu/Debian) or 'brew install redis' (macOS). The hook gracefully exits if Redis tools are unavailable.
Redis server not accessible error during invalidation
Verify Redis is running with 'redis-cli ping'. Check connection settings in redis.conf. The hook tests connectivity before attempting invalidation and exits safely if unreachable.
Too many or too few cache keys being invalidated
Review cache key naming patterns. The hook uses wildcard matching on model names. Use consistent prefixes like 'api:', 'query:', 'model:' for precise pattern matching and control.
Hook triggers on non-model files causing unnecessary scans
The hook only processes files in */models/*, */schemas/*, */entities/* directories. Organize your codebase to match these patterns or customize the path matching logic in the script.
Cache invalidation completes but stale data persists
Check if your application uses multiple Redis databases (DB0, DB1, etc.) or instances. The hook targets the default database. Use 'redis-cli -n <db>' to verify which database stores your cache.
Loading reviews...
Join our community of Claude power users. No spam, unsubscribe anytime.
Automated accessibility testing and compliance checking for web applications following WCAG guidelines
Automatically generates or updates API documentation when endpoint files are modified
Automatically formats code files after Claude writes or edits them using Prettier, Black, or other formatters