final - speedup code for api

This commit is contained in:
mariano
2026-05-22 11:59:05 +02:00
parent 13cb325576
commit 41a8f8dbb4
6 changed files with 251 additions and 241 deletions
+22 -12
View File
@@ -232,7 +232,7 @@ class AssetTab extends CommonDBTM
echo "<td>" . htmlspecialchars(__('UrBackup server version', 'urbackup')) . "</td>";
echo "<td>" . htmlspecialchars((string) ($server->fields['server_version'] ?? '')) . "</td>";
echo "<td>" . htmlspecialchars(__('Client name', 'urbackup')) . "</td>";
echo "<td>" . htmlspecialchars(ServerAsset::getAssetName($item::class, (int) $item->fields['id'])) . "</td>";
echo "<td>" . htmlspecialchars((string) ($item->fields['name'] ?? '')) . "</td>";
echo "</tr>";
echo "</table>";
@@ -263,9 +263,14 @@ class AssetTab extends CommonDBTM
*/
private static function loadApiData(CommonDBTM $item, Server $server, array $link): array
{
$client_name = ServerAsset::getAssetName($item::class, (int) $item->fields['id']);
$client_name = (string) ($item->fields['name'] ?? '');
$asset_ip = ServerAsset::extractAssetIp($item);
$cache_key = 'urbackup_data_' . $server->fields['id'] . '_' . $client_name;
if (isset($_SESSION[$cache_key]) && $_SESSION[$cache_key]['time'] > time() - 30) {
return $_SESSION[$cache_key]['data'];
}
$data = [
'client_found' => false,
'client_status' => [],
@@ -309,6 +314,11 @@ class AssetTab extends CommonDBTM
$data['error'] = $e->getMessage();
}
$_SESSION[$cache_key] = [
'time' => time(),
'data' => $data,
];
return $data;
}
@@ -332,19 +342,19 @@ class AssetTab extends CommonDBTM
$canWrite = Session::haveRight(self::$rightname, UPDATE) || Session::haveRight(self::$rightname, CREATE);
echo '<ul class="nav nav-tabs" id="urbackupTabs">';
echo '<li class="nav-item">';
echo '<a class="nav-link active" id="state-tab" data-bs-toggle="tab" href="#state" role="tab">';
echo '<ul class="nav nav-tabs" id="urbackupTabs" role="tablist">';
echo '<li class="nav-item" role="presentation">';
echo '<a class="nav-link active" id="state-tab" data-bs-toggle="tab" href="#state" role="tab" aria-selected="true">';
echo htmlspecialchars(__('State', 'urbackup'));
echo '</a></li>';
if ($canWrite) {
echo '<li class="nav-item">';
echo '<a class="nav-link" id="actions-tab" data-bs-toggle="tab" href="#actions" role="tab">';
echo '<li class="nav-item" role="presentation">';
echo '<a class="nav-link" id="actions-tab" data-bs-toggle="tab" href="#actions" role="tab" aria-selected="false" tabindex="-1">';
echo htmlspecialchars(__('Actions', 'urbackup'));
echo '</a></li>';
}
echo '<li class="nav-item">';
echo '<a class="nav-link" id="logs-tab" data-bs-toggle="tab" href="#logs" role="tab">';
echo '<li class="nav-item" role="presentation">';
echo '<a class="nav-link" id="logs-tab" data-bs-toggle="tab" href="#logs" role="tab" aria-selected="false" tabindex="-1">';
echo htmlspecialchars(__('Info / Log', 'urbackup'));
echo '</a></li>';
echo '</ul>';
@@ -835,7 +845,7 @@ class AssetTab extends CommonDBTM
return false;
}
$client_name = ServerAsset::getAssetName($item::class, (int) $item->fields['id']);
$client_name = (string) ($item->fields['name'] ?? '');
if ($client_name === '') {
return false;
}
@@ -873,7 +883,7 @@ class AssetTab extends CommonDBTM
return false;
}
$client_name = ServerAsset::getAssetName($item::class, (int) $item->fields['id']);
$client_name = (string) ($item->fields['name'] ?? '');
if ($client_name === '') {
return false;
}
@@ -903,7 +913,7 @@ class AssetTab extends CommonDBTM
return false;
}
$client_name = ServerAsset::getAssetName($item::class, (int) $item->fields['id']);
$client_name = (string) ($item->fields['name'] ?? '');
if ($client_name === '') {
return false;
}
+119 -13
View File
@@ -1125,6 +1125,7 @@ class Server extends CommonDBTM
$itemtypes = Config::getEnabledItemtypes();
$missingAssets = [];
$candidatesByType = [];
foreach ($itemtypes as $itemtype) {
if (!class_exists($itemtype)) {
@@ -1174,25 +1175,34 @@ class Server extends CommonDBTM
$locationName = self::getCachedLocationName($assetLocationId, $cacheLocation);
$stateName = self::getCachedName('State', (int) ($assetRow['states_id'] ?? 0), $cacheState);
$userName = self::getCachedName('User', (int) ($assetRow['users_id'] ?? 0), $cacheUser);
$groupName = self::getAssetGroupName($itemtype, $assetId, $cacheGroup);
$ip = self::getAssetIp($itemtype, $assetId);
$missingAssets[] = [
'itemtype' => $itemtype,
'items_id' => $assetId,
'name' => $name,
'entity' => $entityName,
'location' => $locationName,
'otherserial' => (string) ($assetRow['otherserial'] ?? ''),
'ip' => $ip,
'state' => $stateName,
'user' => $userName,
'group' => $groupName,
'itemtype' => $itemtype,
'items_id' => $assetId,
'name' => $name,
'entity' => $entityName,
'location' => $locationName,
'otherserial' => (string) ($assetRow['otherserial'] ?? ''),
'state' => $stateName,
'user' => $userName,
];
$candidatesByType[$itemtype][] = $assetId;
}
}
$batchIps = self::batchLoadIps($candidatesByType);
$batchGroups = self::batchLoadGroups($candidatesByType);
foreach ($missingAssets as &$asset) {
$key = $asset['itemtype'] . ':' . $asset['items_id'];
$asset['ip'] = $batchIps[$key] ?? '';
$groupId = $batchGroups[$key] ?? 0;
$asset['group'] = $groupId > 0
? self::getCachedName('Group', $groupId, $cacheGroup)
: '';
}
unset($asset);
if (count($missingAssets) === 0) {
echo '<div class="alert alert-success">';
echo htmlspecialchars(__('All assets in this location are linked or already on the UrBackup server.', 'urbackup'));
@@ -1325,6 +1335,102 @@ JAVASCRIPT;
return $cache[$id];
}
/**
* Batch-load IPs for multiple assets across itemtypes.
*
* @param array<string, list<int>> $candidatesByType itemtype => [items_id, ...]
*
* @return array<string, string> key "itemtype:items_id" => IP
*/
private static function batchLoadIps(array $candidatesByType): array
{
global $DB;
$ips = [];
foreach ($candidatesByType as $itemtype => $ids) {
if (count($ids) === 0) {
continue;
}
$iterator = $DB->request([
'SELECT' => ['np.items_id', 'ipa.name'],
'FROM' => 'glpi_ipaddresses AS ipa',
'INNER JOIN' => [
'glpi_networknames AS nn' => [
'ON' => [
'nn' => 'items_id',
'ipa' => 'id',
['AND' => ['ipa.itemtype' => 'NetworkName']],
],
],
'glpi_networkports AS np' => [
'ON' => [
'np' => 'id',
'nn' => 'items_id',
['AND' => ['nn.itemtype' => 'NetworkPort']],
],
],
],
'WHERE' => [
'np.itemtype' => $itemtype,
'np.items_id' => $ids,
],
]);
foreach ($iterator as $row) {
$ip = (string) ($row['name'] ?? '');
if ($ip === '') {
continue;
}
$key = $itemtype . ':' . $row['items_id'];
if (!isset($ips[$key])) {
$ips[$key] = $ip;
}
}
}
return $ips;
}
/**
* Batch-load group IDs for multiple assets across itemtypes.
*
* @param array<string, list<int>> $candidatesByType itemtype => [items_id, ...]
*
* @return array<string, int> key "itemtype:items_id" => groups_id
*/
private static function batchLoadGroups(array $candidatesByType): array
{
global $DB;
$groups = [];
foreach ($candidatesByType as $itemtype => $ids) {
if (count($ids) === 0) {
continue;
}
$iterator = $DB->request([
'FROM' => 'glpi_groups_items',
'WHERE' => [
'itemtype' => $itemtype,
'items_id' => $ids,
'type' => \Group_Item::GROUP_TYPE_NORMAL,
],
]);
foreach ($iterator as $row) {
$key = $itemtype . ':' . $row['items_id'];
if (!isset($groups[$key])) {
$groups[$key] = (int) ($row['groups_id'] ?? 0);
}
}
}
return $groups;
}
private static function getAssetGroupName(string $itemtype, int $items_id, array &$cache): string
{
global $DB;
+32 -6
View File
@@ -37,6 +37,10 @@ class UrbackupApiClient
private int $lastlogid = 0;
private ?array $cached_status = null;
private array $cached_settings = [];
private string $server_version = '';
private bool $is_version_2_4_or_higher = false;
@@ -247,21 +251,29 @@ class UrbackupApiClient
*/
public function getStatus(): array
{
if ($this->cached_status !== null) {
return $this->cached_status;
}
$data = $this->apiAction('status');
if (isset($data['status']) && is_array($data['status'])) {
return array_values($data['status']);
$this->cached_status = array_values($data['status']);
return $this->cached_status;
}
if (isset($data['clients']) && is_array($data['clients'])) {
return array_values($data['clients']);
$this->cached_status = array_values($data['clients']);
return $this->cached_status;
}
if (array_is_list($data)) {
return $data;
$this->cached_status = $data;
return $this->cached_status;
}
return [];
$this->cached_status = [];
return $this->cached_status;
}
/**
@@ -317,16 +329,22 @@ class UrbackupApiClient
return [];
}
if (isset($this->cached_settings[$client_id])) {
return $this->cached_settings[$client_id];
}
$data = $this->apiAction('settings', [
'sa' => 'clientsettings',
't_clientid' => $client_id,
]);
if (isset($data['settings']) && is_array($data['settings'])) {
return $data['settings'];
$this->cached_settings[$client_id] = $data['settings'];
return $this->cached_settings[$client_id];
}
return $data;
$this->cached_settings[$client_id] = $data;
return $this->cached_settings[$client_id];
}
/**
@@ -338,6 +356,11 @@ class UrbackupApiClient
*
* @return bool
*/
private function clearSettingsCache(int $client_id): void
{
unset($this->cached_settings[$client_id]);
}
public function changeClientSetting(string $client_name, string $key, mixed $value): bool
{
$client_id = $this->getClientIdByName($client_name);
@@ -353,6 +376,7 @@ class UrbackupApiClient
$key => (string) $value,
]);
$this->clearSettingsCache($client_id);
return $this->responseIsSuccess($data);
}
@@ -371,6 +395,7 @@ class UrbackupApiClient
$key => $value,
]);
$this->clearSettingsCache($client_id);
return $this->responseIsSuccess($data);
}
@@ -393,6 +418,7 @@ class UrbackupApiClient
$data = $this->apiAction('settings', $params);
$this->clearSettingsCache($client_id);
return $this->responseIsSuccess($data);
}