getClient(); $redis->ping(); echo " ✅ Redis connected successfully\n"; } catch (Exception $e) { echo " ❌ Redis connection failed: " . $e->getMessage() . "\n"; exit(1); } // Create Redis cache $cacheDriver = new RedisCache($redisConnection); $cache = new GeneralCache($cacheDriver, $serializer); echo "\n2. Creating Discovery Service with Redis cache:\n"; $factory = new DiscoveryServiceFactory($container, $pathProvider, $cache, $clock); $discoveryService = $factory->createForDevelopment([$srcPath]); echo " ✅ Discovery service created\n"; // Clear any existing cache echo "\n3. Clearing existing cache:\n"; $redis = $redisConnection->getClient(); $keys = $redis->keys('cache:discovery:*'); if (! empty($keys)) { $redis->del($keys); echo " ✅ Cleared " . count($keys) . " existing cache keys\n"; } else { echo " ✅ No existing cache keys found\n"; } // First discovery run - should cache echo "\n4. First discovery run (should miss cache):\n"; $startTime = microtime(true); $registry1 = $discoveryService->discover(); $firstRunTime = (microtime(true) - $startTime) * 1000; echo " Items discovered: " . count($registry1) . "\n"; echo " Time taken: " . number_format($firstRunTime, 2) . "ms\n"; // Check cache keys $cacheKeys = $redis->keys('cache:discovery:*'); echo " Cache keys after first run: " . count($cacheKeys) . "\n"; foreach ($cacheKeys as $key) { $ttl = $redis->ttl($key); $size = strlen($redis->get($key)); echo " - $key (TTL: {$ttl}s, Size: " . number_format($size) . " bytes)\n"; } // Second discovery run - should hit cache echo "\n5. Second discovery run (should hit cache):\n"; $startTime = microtime(true); $registry2 = $discoveryService->discover(); $secondRunTime = (microtime(true) - $startTime) * 1000; echo " Items discovered: " . count($registry2) . "\n"; echo " Time taken: " . number_format($secondRunTime, 2) . "ms\n"; // Performance comparison $speedup = $firstRunTime / $secondRunTime; echo " Speedup: " . number_format($speedup, 2) . "x\n"; if ($speedup > 2) { echo " ✅ Cache is working effectively\n"; } else { echo " ⚠️ Cache may not be working (speedup should be >2x)\n"; } // Verify identical results echo "\n6. Verifying cache integrity:\n"; if (count($registry1) === count($registry2)) { echo " ✅ Same number of items returned\n"; } else { echo " ❌ Different number of items: " . count($registry1) . " vs " . count($registry2) . "\n"; } // Test cache invalidation after file modification echo "\n7. Testing cache invalidation (simulated file change):\n"; // We can't actually modify files, but we can check the cache mechanism // Manual cache key inspection echo "\n8. Cache key analysis:\n"; $cacheKeys = $redis->keys('cache:discovery:*'); foreach ($cacheKeys as $key) { $data = $redis->get($key); $uncompressed = $data; if (str_starts_with($data, "\x1f\x8b")) { // gzip signature $uncompressed = gzuncompress($data); echo " Key: $key (compressed, original: " . number_format(strlen($data)) . " bytes, expanded: " . number_format(strlen($uncompressed)) . " bytes)\n"; } else { echo " Key: $key (uncompressed, size: " . number_format(strlen($data)) . " bytes)\n"; } // Try to unserialize and check structure try { $unserialized = $serializer->deserialize($uncompressed); echo " - Unserialization: SUCCESS\n"; echo " - Data type: " . gettype($unserialized) . "\n"; if (is_object($unserialized)) { echo " - Object class: " . get_class($unserialized) . "\n"; } } catch (Exception $e) { echo " - Unserialization: FAILED - " . $e->getMessage() . "\n"; } } } catch (Exception $e) { echo "❌ Error: " . $e->getMessage() . "\n"; echo "Stack trace:\n" . $e->getTraceAsString() . "\n"; }