| 1 |
<?php |
| 2 |
|
| 3 |
namespace SyncBasalam\Services; |
| 4 |
|
| 5 |
defined('ABSPATH') || exit; |
| 6 |
|
| 7 |
class SystemResourceMonitor |
| 8 |
{ |
| 9 |
private function getMemoryLimit() |
| 10 |
{ |
| 11 |
$memoryLimit = ini_get('memory_limit'); |
| 12 |
|
| 13 |
if ($memoryLimit == -1) { |
| 14 |
return PHP_INT_MAX; |
| 15 |
} |
| 16 |
|
| 17 |
$unit = strtoupper(substr($memoryLimit, -1)); |
| 18 |
$value = (int) $memoryLimit; |
| 19 |
|
| 20 |
switch ($unit) { |
| 21 |
case 'G': |
| 22 |
$value *= 1024; |
| 23 |
// no break |
| 24 |
case 'M': |
| 25 |
$value *= 1024; |
| 26 |
// no break |
| 27 |
case 'K': |
| 28 |
$value *= 1024; |
| 29 |
} |
| 30 |
|
| 31 |
return $value; |
| 32 |
} |
| 33 |
|
| 34 |
private function getMemoryUsage() |
| 35 |
{ |
| 36 |
return memory_get_usage(true); |
| 37 |
} |
| 38 |
|
| 39 |
private function getAvailableMemory() |
| 40 |
{ |
| 41 |
$limit = $this->getMemoryLimit(); |
| 42 |
$usage = $this->getMemoryUsage(); |
| 43 |
|
| 44 |
return max(0, $limit - $usage); |
| 45 |
} |
| 46 |
|
| 47 |
private function getMemoryScore() |
| 48 |
{ |
| 49 |
$limit = $this->getMemoryLimit(); |
| 50 |
$available = $this->getAvailableMemory(); |
| 51 |
|
| 52 |
if ($limit == PHP_INT_MAX) return 100; |
| 53 |
|
| 54 |
$usagePercent = (($limit - $available) / $limit) * 100; |
| 55 |
|
| 56 |
if ($usagePercent < 30) return 100; |
| 57 |
elseif ($usagePercent < 50) return 80; |
| 58 |
elseif ($usagePercent < 70) return 60; |
| 59 |
elseif ($usagePercent < 85) return 40; |
| 60 |
else return 20; |
| 61 |
} |
| 62 |
|
| 63 |
private function getExecutionTimeScore() |
| 64 |
{ |
| 65 |
$maxExecutionTime = ini_get('max_execution_time'); |
| 66 |
|
| 67 |
if ($maxExecutionTime == 0) return 100; |
| 68 |
|
| 69 |
if ($maxExecutionTime >= 300) return 100; |
| 70 |
elseif ($maxExecutionTime >= 120) return 80; |
| 71 |
elseif ($maxExecutionTime >= 60) return 60; |
| 72 |
elseif ($maxExecutionTime >= 30) return 40; |
| 73 |
else return 20; |
| 74 |
} |
| 75 |
|
| 76 |
private function getPhpVersionScore() |
| 77 |
{ |
| 78 |
$version = PHP_VERSION_ID; |
| 79 |
|
| 80 |
if ($version >= 80000) return 100; |
| 81 |
elseif ($version >= 70400) return 90; |
| 82 |
elseif ($version >= 70000) return 70; |
| 83 |
else return 40; |
| 84 |
} |
| 85 |
|
| 86 |
private function getServerLoadScore() |
| 87 |
{ |
| 88 |
if (function_exists('sys_getloadavg')) { |
| 89 |
$load = sys_getloadavg(); |
| 90 |
if ($load && is_array($load)) { |
| 91 |
$load1min = $load[0]; |
| 92 |
|
| 93 |
$cpuCores = $this->estimateCpuCores(); |
| 94 |
|
| 95 |
$loadPerCore = $load1min / $cpuCores; |
| 96 |
|
| 97 |
if ($loadPerCore < 0.5) return 100; |
| 98 |
elseif ($loadPerCore < 1.0) return 80; |
| 99 |
elseif ($loadPerCore < 2.0) return 60; |
| 100 |
elseif ($loadPerCore < 3.0) return 40; |
| 101 |
else return 20; |
| 102 |
} |
| 103 |
} |
| 104 |
|
| 105 |
return 60; |
| 106 |
} |
| 107 |
|
| 108 |
private function estimateCpuCores() |
| 109 |
{ |
| 110 |
$cores = 2; |
| 111 |
|
| 112 |
$cachedCores = get_transient('sync_basalam_cpu_cores'); |
| 113 |
if ($cachedCores !== false) { |
| 114 |
return (int) $cachedCores; |
| 115 |
} |
| 116 |
|
| 117 |
if (defined('WP_MEMORY_LIMIT')) { |
| 118 |
$wpMemory = wp_convert_hr_to_bytes(WP_MEMORY_LIMIT); |
| 119 |
|
| 120 |
if ($wpMemory >= 4 * 1024 * 1024 * 1024) { |
| 121 |
$cores = 8; |
| 122 |
} elseif ($wpMemory >= 2 * 1024 * 1024 * 1024) { |
| 123 |
$cores = 4; |
| 124 |
} elseif ($wpMemory >= 1024 * 1024 * 1024) { |
| 125 |
$cores = 2; |
| 126 |
} |
| 127 |
} |
| 128 |
|
| 129 |
$memoryLimit = $this->getMemoryLimit(); |
| 130 |
if ($memoryLimit >= 4 * 1024 * 1024 * 1024) { |
| 131 |
$cores = 8; |
| 132 |
} elseif ($memoryLimit >= 2 * 1024 * 1024 * 1024) { |
| 133 |
$cores = 4; |
| 134 |
} elseif ($memoryLimit >= 512 * 1024 * 1024) { |
| 135 |
$cores = 2; |
| 136 |
} |
| 137 |
|
| 138 |
set_transient('sync_basalam_cpu_cores', $cores, HOUR_IN_SECONDS); |
| 139 |
|
| 140 |
return $cores; |
| 141 |
} |
| 142 |
|
| 143 |
public function calculateOptimalTasksPerMinute() |
| 144 |
{ |
| 145 |
$scores = [ |
| 146 |
'memory' => $this->getMemoryScore(), |
| 147 |
'execution_time' => $this->getExecutionTimeScore(), |
| 148 |
'php_version' => $this->getPhpVersionScore(), |
| 149 |
'server_load' => $this->getServerLoadScore(), |
| 150 |
]; |
| 151 |
|
| 152 |
$weights = [ |
| 153 |
'memory' => 0.25, |
| 154 |
'execution_time' => 0.20, |
| 155 |
'server_load' => 0.20, |
| 156 |
'php_version' => 0.05, |
| 157 |
]; |
| 158 |
|
| 159 |
$weightedScore = 0; |
| 160 |
foreach ($scores as $key => $score) { |
| 161 |
$weightedScore += $score * $weights[$key]; |
| 162 |
} |
| 163 |
|
| 164 |
if ($weightedScore < 20) { |
| 165 |
$tasksPerMinute = 1 + (int) (($weightedScore / 20) * 4); |
| 166 |
} elseif ($weightedScore < 40) { |
| 167 |
$tasksPerMinute = 3 + (int) ((($weightedScore - 20) / 20) * 10); |
| 168 |
} elseif ($weightedScore < 60) { |
| 169 |
$tasksPerMinute = 7 + (int) ((($weightedScore - 40) / 20) * 15); |
| 170 |
} elseif ($weightedScore < 80) { |
| 171 |
$tasksPerMinute = 10 + (int) ((($weightedScore - 60) / 20) * 15); |
| 172 |
} else { |
| 173 |
$tasksPerMinute = 12 + (int) ((($weightedScore - 80) / 20) * 15); |
| 174 |
} |
| 175 |
|
| 176 |
return max(1, min(60, $tasksPerMinute)); |
| 177 |
} |
| 178 |
|
| 179 |
public function getSystemInfo() |
| 180 |
{ |
| 181 |
return [ |
| 182 |
'optimal_tasks_per_minute' => $this->calculateOptimalTasksPerMinute(), |
| 183 |
]; |
| 184 |
} |
| 185 |
} |
| 186 |
|