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.
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user