Skip to content

Commit 6753267

Browse files
committed
Getting ready for dev
1 parent d509c14 commit 6753267

10 files changed

Lines changed: 3746 additions & 3621 deletions

cache/__tests__/cache-metrics-worst-case.sh

Lines changed: 273 additions & 185 deletions
Large diffs are not rendered by default.

cache/__tests__/cache-metrics.sh

Lines changed: 73 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,12 +1077,11 @@ cleanup_test_objects() {
10771077

10781078
generate_report() {
10791079
log_header "Generating Report"
1080-
1080+
10811081
local cache_stats=$(get_cache_stats)
10821082
local cache_hits=$(echo "$cache_stats" | grep -o '"hits":[0-9]*' | cut -d: -f2)
10831083
local cache_misses=$(echo "$cache_stats" | grep -o '"misses":[0-9]*' | cut -d: -f2)
10841084
local cache_size=$(echo "$cache_stats" | grep -o '"length":[0-9]*' | cut -d: -f2)
1085-
local cache_invalidations=$(echo "$cache_stats" | grep -o '"invalidations":[0-9]*' | cut -d: -f2)
10861085

10871086
cat > "$REPORT_FILE" << EOF
10881087
# RERUM Cache Metrics & Functionality Report
@@ -1105,7 +1104,6 @@ generate_report() {
11051104
| Cache Misses | ${cache_misses:-0} |
11061105
| Hit Rate | $(echo "$cache_stats" | grep -o '"hitRate":"[^"]*"' | cut -d'"' -f4) |
11071106
| Cache Size | ${cache_size:-0} entries |
1108-
| Invalidations | ${cache_invalidations:-0} |
11091107
11101108
---
11111109
@@ -1315,7 +1313,7 @@ The cache layer provides:
13151313
In production, monitor:
13161314
- **Hit rate**: Target 60-80% for optimal benefit
13171315
- **Evictions**: Should be minimal; increase cache size if frequent
1318-
- **Invalidation count**: Should correlate with write operations
1316+
- **Cache size changes**: Track cache size over time to understand invalidation patterns
13191317
- **Response times**: Track p50, p95, p99 for all endpoints
13201318
13211319
### ⚙️ Configuration Tuning
@@ -2237,28 +2235,48 @@ main() {
22372235
# Get starting state at beginning of Phase 5
22382236
local stats_before_phase5=$(get_cache_stats)
22392237
local starting_cache_size=$(echo "$stats_before_phase5" | grep -o '"length":[0-9]*' | sed 's/"length"://')
2240-
local invalidations_before_phase5=$(echo "$stats_before_phase5" | grep -o '"invalidations":[0-9]*' | sed 's/"invalidations"://')
2241-
2238+
local starting_evictions=$(echo "$stats_before_phase5" | grep -o '"evictions":[0-9]*' | sed 's/"evictions"://')
2239+
2240+
# Track invalidations ourselves (app doesn't track them)
2241+
# Invalidations = cache size decrease from write operations
2242+
local total_invalidations=0
2243+
22422244
log_info "=== PHASE 5 STARTING STATE ==="
22432245
log_info "Starting cache size: $starting_cache_size entries"
2244-
log_info "Invalidations before Phase 5: $invalidations_before_phase5"
22452246
log_info "Phase 3 filled cache with queries matching Phase 5 write operation types"
22462247
log_info "Each write operation should invalidate multiple cache entries"
2248+
log_info "Test will calculate invalidations as cache size decrease per write operation"
22472249

22482250
echo "[INFO] Running write endpoint tests..."
22492251

22502252
# Cache is already full from Phase 3 - reuse it without refilling
22512253

2252-
# Helper function to log cache changes
2254+
# Helper function to log cache changes and calculate invalidations
2255+
# Write operations don't add cache entries, so size decrease = invalidations
2256+
local size_before=$starting_cache_size
2257+
22532258
track_cache_change() {
22542259
local operation=$1
22552260
local stats=$(get_cache_stats)
2256-
local size=$(echo "$stats" | grep -o '"length":[0-9]*' | sed 's/"length"://')
2257-
local invalidations=$(echo "$stats" | grep -o '"invalidations":[0-9]*' | sed 's/"invalidations"://')
2261+
local size_after=$(echo "$stats" | grep -o '"length":[0-9]*' | sed 's/"length"://')
22582262
local evictions=$(echo "$stats" | grep -o '"evictions":[0-9]*' | sed 's/"evictions"://')
2259-
local sets=$(echo "$stats" | grep -o '"sets":[0-9]*' | sed 's/"sets"://')
2260-
2261-
echo "[CACHE TRACK] After $operation: size=$size, invalidations=$invalidations (Δ+$((invalidations - invalidations_before_phase5))), evictions=$evictions, sets=$sets" >&2
2263+
2264+
# Calculate invalidations for this operation
2265+
# Write operations don't add cache entries, so size decrease = invalidations only
2266+
local operation_invalidations=$((size_before - size_after))
2267+
2268+
# Ensure non-negative
2269+
if [ $operation_invalidations -lt 0 ]; then
2270+
operation_invalidations=0
2271+
fi
2272+
2273+
# Accumulate total
2274+
total_invalidations=$((total_invalidations + operation_invalidations))
2275+
2276+
echo "[CACHE TRACK] After $operation: size=$size_after (Δ-$operation_invalidations invalidations), evictions=$evictions, total_invalidations=$total_invalidations" >&2
2277+
2278+
# Update size for next operation
2279+
size_before=$size_after
22622280
}
22632281

22642282
# DEBUG: Log cache state before each write test
@@ -2286,34 +2304,41 @@ main() {
22862304

22872305
test_delete_endpoint_full
22882306

2289-
log_info "Waiting for cache invalidations and stats to sync across all PM2 workers..."
2307+
log_info "Waiting for cache stats to sync across all PM2 workers..."
22902308
log_info "Stats sync every 5 seconds - waiting 12 seconds to ensure at least two sync cycles complete..."
22912309
sleep 12
2292-
2310+
22932311
local stats_after_phase5=$(get_cache_stats)
22942312
local final_cache_size=$(echo "$stats_after_phase5" | grep -o '"length":[0-9]*' | sed 's/"length"://')
2295-
local invalidations_after_phase5=$(echo "$stats_after_phase5" | grep -o '"invalidations":[0-9]*' | sed 's/"invalidations"://')
2296-
2297-
local total_invalidations=$((invalidations_after_phase5 - invalidations_before_phase5))
2298-
local actual_entries_removed=$((starting_cache_size - final_cache_size))
2299-
2300-
local total_invalidations=$((invalidations_after_phase5 - invalidations_before_phase5))
2313+
local final_evictions=$(echo "$stats_after_phase5" | grep -o '"evictions":[0-9]*' | sed 's/"evictions"://')
2314+
23012315
local actual_entries_removed=$((starting_cache_size - final_cache_size))
2316+
local total_evictions=$((final_evictions - starting_evictions))
2317+
2318+
# total_invalidations was calculated incrementally by track_cache_change()
2319+
# Verify it matches our overall size reduction (should be close, minor differences due to timing)
2320+
if [ $total_invalidations -ne $actual_entries_removed ]; then
2321+
local diff=$((actual_entries_removed - total_invalidations))
2322+
if [ ${diff#-} -gt 2 ]; then # Allow ±2 difference for timing
2323+
log_warning "Invalidation count variance: incremental=$total_invalidations, overall_removed=$actual_entries_removed (diff: $diff)"
2324+
fi
2325+
fi
23022326

23032327
echo ""
23042328
log_info "=== PHASE 5 FINAL RESULTS ==="
23052329
log_info "Starting cache size: $starting_cache_size entries (after adding 5 test queries)"
23062330
log_info "Final cache size: $final_cache_size entries"
2307-
log_info "Actual entries removed: $actual_entries_removed entries"
2331+
log_info "Total cache size reduction: $actual_entries_removed entries"
2332+
log_info "Calculated invalidations: $total_invalidations entries (from write operations)"
2333+
log_info "LRU evictions during phase: $total_evictions (separate from invalidations)"
23082334
log_info ""
23092335
log_info "=== PHASE 5 CACHE ACCOUNTING ==="
23102336
log_info "Initial state: ${starting_cache_size} entries"
23112337
log_info " - Cache filled to 1000 in Phase 3"
23122338
log_info " - Added 5 query entries for write tests (matched test object types)"
2313-
log_info " - Starting invalidations: ${invalidations_before_phase5}"
23142339
log_info ""
23152340
log_info "Write operations performed:"
2316-
log_info " - create: 100 operations (no existing data, minimal invalidation)"
2341+
log_info " - create: 100 operations (minimal invalidation - no existing data)"
23172342
log_info " - update: 50 operations (invalidates id:*, history:*, since:*, matching queries)"
23182343
log_info " - patch: 50 operations (invalidates id:*, history:*, since:*, matching queries)"
23192344
log_info " - set: 50 operations (invalidates id:*, history:*, since:*, matching queries)"
@@ -2322,28 +2347,21 @@ main() {
23222347
log_info " - delete: 50 operations (invalidates id:*, history:*, since:* for each)"
23232348
log_info ""
23242349
log_info "Final state: ${final_cache_size} entries"
2325-
log_info " - Entries removed: ${actual_entries_removed}"
2326-
log_info " - Invalidations recorded: ${total_invalidations}"
2327-
log_info " - Final invalidations: ${invalidations_after_phase5}"
2350+
log_info " - Invalidations from writes: ${total_invalidations}"
2351+
log_info " - LRU evictions (separate): ${total_evictions}"
2352+
log_info " - Total size reduction: ${actual_entries_removed}"
23282353
echo ""
23292354

2330-
# Validate that invalidations and removals are in the expected range
2355+
# Validate that calculated invalidations are in the expected range
23312356
if [ -n "$final_cache_size" ] && [ -n "$total_invalidations" ]; then
2332-
# Calculate difference between invalidations and actual removals
2333-
local invalidation_diff=$((total_invalidations - actual_entries_removed))
2334-
local invalidation_diff_abs=${invalidation_diff#-} # Absolute value
2335-
2336-
# Important: invalidations count entries actually deleted from cache
2337-
# actual_entries_removed may be larger because it includes:
2338-
# - Invalidations (entries deleted)
2339-
# - LRU evictions (entries removed due to cache limits)
2340-
# - Entries that didn't exist (e.g., id:* keys never cached)
2341-
#
2357+
# total_invalidations = cumulative cache size decrease from each write operation
2358+
# This represents entries removed by invalidation logic during writes
2359+
23422360
# For DELETE operations:
23432361
# - Each DELETE tries to invalidate 3 keys: id:*, history:*, since:*
23442362
# - But id:* only exists if /id/:id was called for that object
2345-
# - history:* and since:* always exist (created during reads)
2346-
# - So we expect ~2 invalidations per DELETE (not 3)
2363+
# - history:* and since:* are created during read operations
2364+
# - So we expect ~2 invalidations per DELETE on average (not 3)
23472365

23482366
# Calculate expected invalidations based on test operations
23492367
local num_deletes=50
@@ -2366,22 +2384,25 @@ main() {
23662384
log_info "Note: Variance can occur if some objects were cached via /id/:id endpoint"
23672385
fi
23682386

2369-
# Additional check for suspiciously low invalidation counts (stats sync issue)
2387+
# Additional check for suspiciously low invalidation counts
23702388
if [ $total_invalidations -lt 25 ]; then
23712389
log_warning "⚠️ Invalidation count ($total_invalidations) is lower than expected minimum (~25)"
2372-
log_info "This is likely due to PM2 cluster stats aggregation timing"
2373-
log_info "Cache behavior is correct (${actual_entries_removed} entries removed), but stats under-reported"
2374-
log_info "Note: Stats sync wait time is 12s - if this warning persists, check atomic increment implementation"
2390+
log_info "Possible causes:"
2391+
log_info " - Write operations may not have matched many cached queries"
2392+
log_info " - Phase 3 cache fill may not have created many matching entries"
2393+
log_info " - Total size reduction: ${actual_entries_removed}, Invalidations tracked: ${total_invalidations}"
23752394
fi
2376-
2377-
# Verify the relationship: actual_entries_removed >= total_invalidations
2378-
# (removals include invalidations + evictions + non-existent keys)
2379-
if [ $actual_entries_removed -ge $total_invalidations ]; then
2380-
log_success "✅ Cache behavior correct: $actual_entries_removed entries removed ≥ $total_invalidations invalidations"
2381-
log_info "Difference ($invalidation_diff_abs) includes: LRU evictions, non-existent keys, or cluster sync timing"
2395+
2396+
# Verify invalidations are reasonable (should be most of the size reduction)
2397+
# Note: Evictions happen asynchronously during reads, not during writes
2398+
# So invalidations should be close to total size reduction
2399+
if [ $total_invalidations -eq $actual_entries_removed ]; then
2400+
log_success "✅ All cache size reduction from invalidations: $total_invalidations entries"
2401+
elif [ $((actual_entries_removed - total_invalidations)) -le 5 ]; then
2402+
log_success "✅ Most cache reduction from invalidations: $total_invalidations of $actual_entries_removed entries"
23822403
else
2383-
log_warning "⚠️ Unexpected: fewer entries removed ($actual_entries_removed) than invalidations ($total_invalidations)"
2384-
log_info "This may indicate an issue with invalidation tracking"
2404+
log_info "ℹ️ Cache reduction: $total_invalidations invalidations, $actual_entries_removed total removed"
2405+
log_info "Difference may be due to concurrent operations or timing between measurements"
23852406
fi
23862407

23872408
# Report cache size reduction

0 commit comments

Comments
 (0)