Skip to content

Commit 19abdfb

Browse files
committed
Add cleanupExpiredManagedKeys method to SmartCache for managing expired keys and update ClearCommand to report on expired keys cleaned. Enhance performance metrics with configurable thresholds for warnings.
1 parent 48fe7ba commit 19abdfb

File tree

5 files changed

+138
-15
lines changed

5 files changed

+138
-15
lines changed

src/Console/Commands/ClearCommand.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,23 @@ protected function clearAllKeys(SmartCache $cache): int
100100

101101
$this->info("Clearing {$count} SmartCache managed items...");
102102

103+
// Clean up expired keys first and report
104+
$expiredCleaned = $cache->cleanupExpiredManagedKeys();
105+
if ($expiredCleaned > 0) {
106+
$this->info("Cleaned up {$expiredCleaned} expired keys from tracking list.");
107+
}
108+
109+
// Get updated key count after cleanup
110+
$keys = $cache->getManagedKeys();
111+
$actualCount = count($keys);
112+
113+
if ($actualCount === 0) {
114+
$this->info('All managed keys were expired and have been cleaned up.');
115+
return 0;
116+
}
117+
118+
$this->info("Clearing {$actualCount} active SmartCache managed items...");
119+
103120
$success = $cache->clear();
104121

105122
if ($success) {
@@ -113,6 +130,7 @@ protected function clearAllKeys(SmartCache $cache): int
113130
return 0;
114131
} else {
115132
$this->error('Some SmartCache items could not be cleared.');
133+
$this->comment('This may be due to cache driver limitations or permission issues.');
116134
return 1;
117135
}
118136
}

src/Contracts/SmartCache.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,21 @@ public function clear(): bool;
8888
*/
8989
public function getManagedKeys(): array;
9090

91+
/**
92+
* Clean up expired keys from managed keys tracking.
93+
*
94+
* @return int Number of expired keys removed
95+
*/
96+
public function cleanupExpiredManagedKeys(): int;
97+
98+
/**
99+
* Check if a specific feature is available.
100+
*
101+
* @param string $feature The feature name to check
102+
* @return bool
103+
*/
104+
public function hasFeature(string $feature): bool;
105+
91106
/**
92107
* Tag cache entries for organized invalidation.
93108
*

src/Facades/SmartCache.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
* @method static array getPerformanceMetrics()
3434
* @method static void resetPerformanceMetrics()
3535
* @method static array analyzePerformance()
36+
* @method static int cleanupExpiredManagedKeys()
37+
* @method static bool hasFeature(string $feature)
3638
*
3739
* @see \SmartCache\SmartCache
3840
*/

src/Services/CacheInvalidationService.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public function getCacheStatistics(): array
154154

155155
// Analyze optimization usage
156156
foreach ($managedKeys as $key) {
157-
$value = Cache::get($key);
157+
$value = $this->smartCache->get($key);
158158
if (is_array($value)) {
159159
if (isset($value['_sc_compressed'])) {
160160
$stats['optimization_stats']['compressed']++;
@@ -182,19 +182,23 @@ public function healthCheckAndCleanup(): array
182182
'orphaned_chunks_cleaned' => 0,
183183
'broken_dependencies_fixed' => 0,
184184
'invalid_tags_removed' => 0,
185+
'expired_keys_cleaned' => 0,
185186
'total_keys_checked' => 0,
186187
];
187188

188189
$managedKeys = $this->smartCache->getManagedKeys();
189190
$results['total_keys_checked'] = count($managedKeys);
190191

192+
// Clean up expired managed keys first
193+
$results['expired_keys_cleaned'] = $this->smartCache->cleanupExpiredManagedKeys();
194+
191195
// Check for orphaned chunks
192196
foreach ($managedKeys as $key) {
193-
$value = Cache::get($key);
197+
$value = $this->smartCache->get($key);
194198
if (is_array($value) && isset($value['_sc_chunked'])) {
195199
$missingChunks = 0;
196200
foreach ($value['chunk_keys'] as $chunkKey) {
197-
if (!Cache::has($chunkKey)) {
201+
if (!$this->smartCache->has($chunkKey)) {
198202
$missingChunks++;
199203
}
200204
}

src/SmartCache.php

Lines changed: 96 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,9 @@ public function clear(): bool
256256
{
257257
$success = true;
258258

259+
// Clean up expired keys first
260+
$this->cleanupExpiredManagedKeys();
261+
259262
// Get all tracked keys
260263
$keys = $this->getManagedKeys();
261264

@@ -405,6 +408,62 @@ public function getManagedKeys(): array
405408
return $this->managedKeys;
406409
}
407410

411+
/**
412+
* Clean up expired keys from managed keys tracking.
413+
*
414+
* @return int Number of expired keys removed
415+
*/
416+
public function cleanupExpiredManagedKeys(): int
417+
{
418+
$cleaned = 0;
419+
$validKeys = [];
420+
421+
foreach ($this->managedKeys as $key) {
422+
if ($this->has($key)) {
423+
$validKeys[] = $key;
424+
} else {
425+
$cleaned++;
426+
}
427+
}
428+
429+
if ($cleaned > 0) {
430+
$this->managedKeys = $validKeys;
431+
$this->cache->forever('_sc_managed_keys', $this->managedKeys);
432+
}
433+
434+
return $cleaned;
435+
}
436+
437+
/**
438+
* Check if a specific feature is available.
439+
*
440+
* @param string $feature The feature name to check
441+
* @return bool
442+
*/
443+
public function hasFeature(string $feature): bool
444+
{
445+
$features = [
446+
'tags' => method_exists($this, 'tags'),
447+
'flushTags' => method_exists($this, 'flushTags'),
448+
'dependsOn' => method_exists($this, 'dependsOn'),
449+
'invalidate' => method_exists($this, 'invalidate'),
450+
'flushPatterns' => method_exists($this, 'flushPatterns'),
451+
'invalidateModel' => method_exists($this, 'invalidateModel'),
452+
'swr' => method_exists($this, 'swr'),
453+
'stale' => method_exists($this, 'stale'),
454+
'refreshAhead' => method_exists($this, 'refreshAhead'),
455+
'flexible' => method_exists($this, 'flexible'),
456+
'getStatistics' => method_exists($this, 'getStatistics'),
457+
'healthCheck' => method_exists($this, 'healthCheck'),
458+
'getPerformanceMetrics' => method_exists($this, 'getPerformanceMetrics'),
459+
'analyzePerformance' => method_exists($this, 'analyzePerformance'),
460+
'getAvailableCommands' => method_exists($this, 'getAvailableCommands'),
461+
'executeCommand' => method_exists($this, 'executeCommand'),
462+
];
463+
464+
return $features[$feature] ?? false;
465+
}
466+
408467
/**
409468
* Determines the cache driver from the store instance.
410469
*
@@ -882,13 +941,30 @@ protected function executeClearCommand(array $parameters = []): array
882941
];
883942
}
884943

944+
// Clean up expired keys first
945+
$expiredCleaned = $this->cleanupExpiredManagedKeys();
946+
$keys = $this->getManagedKeys();
947+
$actualCount = count($keys);
948+
949+
if ($actualCount === 0) {
950+
return [
951+
'success' => true,
952+
'message' => "All {$count} managed keys were expired and have been cleaned up.",
953+
'cleared_count' => $count,
954+
'expired_cleaned' => $expiredCleaned,
955+
'total_managed_keys' => $count
956+
];
957+
}
958+
885959
$success = $this->clear();
886960

887961
return [
888962
'success' => $success,
889-
'message' => $success ? "Cleared {$count} SmartCache managed keys." : 'Some keys could not be cleared.',
890-
'cleared_count' => $success ? $count : 0,
891-
'total_managed_keys' => $count
963+
'message' => $success ? "Cleared {$actualCount} SmartCache managed keys." : 'Some keys could not be cleared.',
964+
'cleared_count' => $success ? $actualCount : 0,
965+
'expired_cleaned' => $expiredCleaned,
966+
'total_managed_keys' => $count,
967+
'active_keys_cleared' => $actualCount
892968
];
893969
}
894970
}
@@ -1091,34 +1167,42 @@ public function analyzePerformance(): array
10911167
$efficiency = $metrics['cache_efficiency'];
10921168
$optimization = $metrics['optimization_impact'];
10931169

1170+
// Get warning thresholds from config
1171+
$hitRatioThreshold = $this->config->get('smart-cache.warnings.hit_ratio_threshold', 70);
1172+
$optimizationThreshold = $this->config->get('smart-cache.warnings.optimization_ratio_threshold', 20);
1173+
$slowWriteThreshold = $this->config->get('smart-cache.warnings.slow_write_threshold', 0.1);
1174+
10941175
// Hit ratio recommendations
1095-
if ($efficiency['hit_ratio'] < 70) {
1176+
if ($efficiency['hit_ratio'] < $hitRatioThreshold) {
10961177
$recommendations[] = [
10971178
'type' => 'low_hit_ratio',
10981179
'severity' => 'warning',
1099-
'message' => 'Cache hit ratio is below 70%. Consider increasing TTL values or reviewing cache key strategies.',
1100-
'current_ratio' => $efficiency['hit_ratio']
1180+
'message' => "Cache hit ratio is below {$hitRatioThreshold}%. Consider increasing TTL values or reviewing cache key strategies.",
1181+
'current_ratio' => $efficiency['hit_ratio'],
1182+
'threshold' => $hitRatioThreshold
11011183
];
11021184
}
11031185

11041186
// Optimization recommendations
1105-
if ($optimization['optimization_ratio'] < 20 && $optimization['total_writes'] > 10) {
1187+
if ($optimization['optimization_ratio'] < $optimizationThreshold && $optimization['total_writes'] > 10) {
11061188
$recommendations[] = [
11071189
'type' => 'low_optimization',
11081190
'severity' => 'info',
1109-
'message' => 'Few cache entries are being optimized. Consider adjusting compression/chunking thresholds.',
1110-
'current_ratio' => $optimization['optimization_ratio']
1191+
'message' => "Few cache entries are being optimized. Consider adjusting compression/chunking thresholds.",
1192+
'current_ratio' => $optimization['optimization_ratio'],
1193+
'threshold' => $optimizationThreshold
11111194
];
11121195
}
11131196

11141197
// Performance issues
11151198
$writes = $metrics['metrics']['cache_write'] ?? [];
1116-
if (isset($writes['average_duration']) && $writes['average_duration'] > 0.1) {
1199+
if (isset($writes['average_duration']) && $writes['average_duration'] > $slowWriteThreshold) {
11171200
$recommendations[] = [
11181201
'type' => 'slow_writes',
11191202
'severity' => 'warning',
1120-
'message' => 'Cache write operations are taking longer than 100ms on average.',
1121-
'average_duration' => round($writes['average_duration'] * 1000, 2) . 'ms'
1203+
'message' => "Cache write operations are taking longer than " . round($slowWriteThreshold * 1000) . "ms on average.",
1204+
'average_duration' => round($writes['average_duration'] * 1000, 2) . 'ms',
1205+
'threshold' => round($slowWriteThreshold * 1000) . 'ms'
11221206
];
11231207
}
11241208

0 commit comments

Comments
 (0)