Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Cache\Commands;
|
||||
@@ -7,17 +8,176 @@ use App\Framework\Cache\Cache;
|
||||
use App\Framework\Console\ConsoleCommand;
|
||||
use App\Framework\Console\ConsoleInput;
|
||||
use App\Framework\Console\ConsoleOutput;
|
||||
use App\Framework\Core\PathProvider;
|
||||
use App\Framework\DI\Container;
|
||||
use App\Framework\Redis\RedisConnectionPool;
|
||||
|
||||
final readonly class ClearCache
|
||||
{
|
||||
public function __construct(
|
||||
private Cache $cache,
|
||||
) {}
|
||||
private PathProvider $pathProvider,
|
||||
private Container $container
|
||||
) {
|
||||
}
|
||||
|
||||
#[ConsoleCommand("cache:clear", "Clears the cache")]
|
||||
#[ConsoleCommand("cache:clear", "Clears all caches (application, discovery, routes, opcache, redis)")]
|
||||
public function __invoke(ConsoleInput $input, ConsoleOutput $output): void
|
||||
{
|
||||
$this->cache->clear();
|
||||
$output->writeSuccess("Cache cleared");
|
||||
$cleared = [];
|
||||
|
||||
// Clear OPcache
|
||||
if (function_exists('opcache_reset')) {
|
||||
opcache_reset();
|
||||
$cleared[] = 'OPcache';
|
||||
}
|
||||
|
||||
// Clear Redis cache completely - this is now ALWAYS done
|
||||
// because Discovery cache and other critical framework caches are stored in Redis
|
||||
if ($this->clearRedisCompletely()) {
|
||||
$cleared[] = 'Redis (FLUSHALL)';
|
||||
} else {
|
||||
// Fallback: Clear application cache through Cache interface
|
||||
$this->cache->clear();
|
||||
$cleared[] = 'Application cache (fallback)';
|
||||
}
|
||||
|
||||
// Clear discovery cache files (redundant after Redis FLUSHALL, but safe)
|
||||
$this->clearDiscoveryFiles();
|
||||
$cleared[] = 'Discovery files';
|
||||
|
||||
// Clear routes cache
|
||||
$routesCacheFile = $this->pathProvider->resolvePath('/cache/routes.cache.php');
|
||||
if (file_exists($routesCacheFile)) {
|
||||
unlink($routesCacheFile);
|
||||
$cleared[] = 'Routes cache';
|
||||
}
|
||||
|
||||
// Clear all cache files
|
||||
$this->clearAllCacheFiles();
|
||||
$cleared[] = 'All cache files';
|
||||
|
||||
$output->writeSuccess('Cleared: ' . implode(', ', $cleared));
|
||||
}
|
||||
|
||||
#[ConsoleCommand("redis:flush", "Advanced Redis cache clearing with options")]
|
||||
public function flushRedis(ConsoleInput $input, ConsoleOutput $output): void
|
||||
{
|
||||
$cleared = [];
|
||||
|
||||
if (! $this->container->has(RedisConnectionPool::class)) {
|
||||
$output->writeError('Redis connection pool not available');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$redisPool = $this->container->get(RedisConnectionPool::class);
|
||||
$connection = $redisPool->getConnection('cache');
|
||||
$redis = $connection->getClient();
|
||||
|
||||
// Option: --db to flush specific database
|
||||
if ($input->hasOption('db')) {
|
||||
$database = (int) $input->getOption('db');
|
||||
$redis->select($database);
|
||||
$result = $redis->flushDB();
|
||||
if ($result === true) {
|
||||
$cleared[] = "Redis database $database";
|
||||
} else {
|
||||
$output->writeError("Failed to flush Redis database $database");
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Default: FLUSHALL
|
||||
$result = $redis->flushAll();
|
||||
if ($result === true) {
|
||||
$cleared[] = 'Redis (all databases)';
|
||||
} else {
|
||||
$output->writeError('Failed to flush Redis');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$output->writeSuccess('Cleared: ' . implode(', ', $cleared));
|
||||
} catch (\Throwable $e) {
|
||||
$output->writeError('Redis flush failed: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function clearDiscoveryFiles(): void
|
||||
{
|
||||
$cacheDir = $this->pathProvider->resolvePath('/cache');
|
||||
if (! is_dir($cacheDir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$files = glob($cacheDir . '/discovery_*.cache.php');
|
||||
foreach ($files as $file) {
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function clearAllCacheFiles(): void
|
||||
{
|
||||
$cacheDir = $this->pathProvider->resolvePath('/cache');
|
||||
if (! is_dir($cacheDir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$files = glob($cacheDir . '/*.cache.php');
|
||||
foreach ($files as $file) {
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function clearRedisCompletely(): bool
|
||||
{
|
||||
try {
|
||||
// Strategy 1: Direct Redis connection via RedisConnectionPool (lazy-loaded)
|
||||
try {
|
||||
if ($this->container->has(RedisConnectionPool::class)) {
|
||||
$redisPool = $this->container->get(RedisConnectionPool::class);
|
||||
$connection = $redisPool->getConnection('cache');
|
||||
$redis = $connection->getClient();
|
||||
|
||||
// Use FLUSHALL to clear all Redis databases
|
||||
$result = $redis->flushAll();
|
||||
if ($result === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fallback: FLUSHDB for cache database (database 1)
|
||||
$redis->select(1);
|
||||
$result = $redis->flushDB();
|
||||
if ($result === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
error_log("Direct Redis connection failed: " . $e->getMessage());
|
||||
}
|
||||
|
||||
// Strategy 2: Through cache interface clear method (limited effectiveness)
|
||||
try {
|
||||
$this->cache->clear();
|
||||
|
||||
// Note: This only clears application cache patterns, not Discovery cache
|
||||
return false; // Return false to indicate partial clearing
|
||||
} catch (\Throwable $e) {
|
||||
error_log("Cache interface clear failed: " . $e->getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (\Exception $e) {
|
||||
error_log("Redis cache clear failed: " . $e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user