From 2534ffb1b9177ee4592b8835127a4716fe710065 Mon Sep 17 00:00:00 2001 From: Jeppe Bundgaard Date: Tue, 24 Feb 2026 13:55:34 +0100 Subject: [PATCH] Add Redis caching to autoloader for improved class and module loading performance - Integrated Redis caching in the autoloading process to store and retrieve class and file paths dynamically. - Added fallback mechanisms for Redis errors to ensure compatibility. - Cached module directories and individual class paths with expiration to enhance performance and reduce filesystem scans. --- services/nginx/app/index.php | 62 ++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/services/nginx/app/index.php b/services/nginx/app/index.php index 030b5867..40b8421e 100644 --- a/services/nginx/app/index.php +++ b/services/nginx/app/index.php @@ -22,6 +22,18 @@ header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS"); /** Autoload */ require_once __DIR__ . '/vendor/autoload.php'; + +// Initialize Redis for autoload caching +require_once WD . '/interfaces/redis_i.php'; +require_once WD . '/traits/redis_t.php'; +require_once WD . '/classes/redis.php'; +try { + $redis_instance = (new classes\redis())->connect(); + define("redis", $redis_instance); +} catch (Exception $e) { + // Redis might not be available, autoloader will fall back to manual search +} + /** * Lightweight project autoloader: load classes/interfaces/traits/modules on demand. * Maps top-level namespaces to folders under the app root (WD). @@ -35,6 +47,20 @@ require_once __DIR__ . '/vendor/autoload.php'; */ spl_autoload_register(function (string $class): void { $class = ltrim($class, '\\'); + + // Check Redis cache first + if (defined('redis')) { + try { + $cached = redis->get('autoload:' . $class); + if ($cached && is_file($cached)) { + require_once $cached; + return; + } + } catch (\Throwable $e) { + // Fall back to manual search on Redis error + } + } + $parts = explode('\\', $class); $top = strtolower($parts[0] ?? ''); $relative = implode(DIRECTORY_SEPARATOR, array_slice($parts, 1)); @@ -59,9 +85,22 @@ spl_autoload_register(function (string $class): void { // Try inside each module subfolder (e.g. customers\economicCustomers -> modules/economic/customers/economicCustomers.php) static $module_dirs = null; if ($module_dirs === null) { - $module_dirs = array_filter(scandir($base . 'modules'), function($item) use ($base) { - return $item !== '.' && $item !== '..' && is_dir($base . 'modules' . DIRECTORY_SEPARATOR . $item); - }); + if (defined('redis')) { + try { + $module_dirs = redis->get_array('autoload:module_dirs'); + } catch (\Throwable $e) {} + } + if ($module_dirs === null) { + $module_dirs = array_filter(scandir($base . 'modules'), function($item) use ($base) { + return $item !== '.' && $item !== '..' && is_dir($base . 'modules' . DIRECTORY_SEPARATOR . $item); + }); + if (defined('redis')) { + try { + redis->set_array('autoload:module_dirs', $module_dirs); + redis->expire('autoload:module_dirs', 3600); // Cache for 1 hour + } catch (\Throwable $e) {} + } + } } foreach ($module_dirs as $mod) { $candidates[] = $base . 'modules' . DIRECTORY_SEPARATOR . $mod . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class); @@ -76,6 +115,11 @@ spl_autoload_register(function (string $class): void { if (is_file($file)) { require_once $file; if (class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false) || (function_exists('enum_exists') && enum_exists($class, false))) { + if (defined('redis')) { + try { + redis->setEx('autoload:' . $class, $file, 86400); // Cache for 24 hours + } catch (\Throwable $e) {} + } return; } } @@ -94,10 +138,14 @@ $router = new router(); $response = new response(); $request = new request(); $db = new db($CONFIG_DB); -try { - define("redis", (new redis())->connect()); -} catch (Exception $e) { - $response->error($e->getMessage(), 500); + +// Ensure Redis is connected +if (!defined('redis')) { + try { + define("redis", (new redis())->connect()); + } catch (Exception $e) { + $response->error($e->getMessage(), 500); + } } // Connect to the database, and ensure the connection is successful