2022-02-11 15:48:06 +01:00

166 lines
5.1 KiB
PHP

<?php
/**
* FusionInventory
*
* Copyright (C) 2010-2016 by the FusionInventory Development Team.
*
* http://www.fusioninventory.org/
* https://github.com/fusioninventory/fusioninventory-for-glpi
* http://forge.fusioninventory.org/
*
* ------------------------------------------------------------------------
*
* LICENSE
*
* This file is part of FusionInventory project.
*
* FusionInventory is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FusionInventory is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with FusionInventory. If not, see <http://www.gnu.org/licenses/>.
*
* ------------------------------------------------------------------------
*
* This file is used to manage lock during inventory.
*
* ------------------------------------------------------------------------
*
* @package FusionInventory
* @author Walid Nouh
* @copyright Copyright (c) 2010-2016 FusionInventory team
* @license AGPL License 3.0 or (at your option) any later version
* http://www.gnu.org/licenses/agpl-3.0-standalone.html
* @link http://www.fusioninventory.org/
* @link https://github.com/fusioninventory/fusioninventory-for-glpi
*
*/
if (!defined('GLPI_ROOT')) {
die("Sorry. You can't access directly to this file");
}
/**
* Manage db locks during inventory.
*/
class PluginFusioninventoryDBLock {
//Number of milliseconds to wait each time we check if the lock is set
const MILLISECOND_LOCK_WAIT = 100000;
//Number of second to wait before forcing release of the lock
const SECONDS_TO_RELEASE_LOCK = 600;
//Number of second that is supposed to be the maximum to send to an agent
//an error message explaining that a lock is still in place
const SECONDS_BEFORE_SENDING_ERROR = 5;
/**
* Put a lock to prevent import of software/software version
* @since 9.2+2.0
*
* @param string $type type of lock ('software' or 'softwareversion')
* @param string callback_method the name of the method to call when checking the lock
* @return boolean the result of the lock
*/
function setLock($type, $value = '1', $callback_method = false) {
global $DB, $CFG_GLPI;
$result = true;
$table = "glpi_plugin_fusioninventory_dblock".$type;
if ($DB->tableExists($table)) {
$start_time = date('U');
//Set a lock for softwares to prevent new software import
$CFG_GLPI["use_log_in_files"] = false;
$query = $DB->buildInsert(
$table, [
'value' => $value
]
);
while (!$DB->query($query)) {
usleep(self::MILLISECOND_LOCK_WAIT);
if ($callback_method) {
$result = $this->checkLockForAgents($start_time);
if (!$result) {
break;
}
}
}
$CFG_GLPI["use_log_in_files"] = true;
}
return $result;
}
/**
* Check if a lock error message should be sent an agent
* @since 9.2+2.0
*
* @param string $start_time the time where we start trying to set the lock
* @return boolean true if no error message should
*/
function checkLockForAgents($start_time) {
if ((date('U') - $start_time) > self::SECONDS_BEFORE_SENDING_ERROR) {
$communication = new PluginFusioninventoryCommunication();
$communication->setMessage("<?xml version='1.0' encoding='UTF-8'?>
<REPLY>
<ERROR>ERROR: Timeout for DB lock based on name</ERROR>
</REPLY>");
$communication->sendMessage($_SESSION['plugin_fusioninventory_compressmode']);
return false;
}
return true;
}
/**
* Put a lock to prevent import of software/software version
* @since 9.2+2.0
*
* @param string $type type of lock ('software' or 'softwareversion')
* @param string $where the SQL where clause to use to release lock (default '')
*/
function releaseLock($type, $where = []) {
global $DB;
if (empty($where)) {
$where = ['value' => '1'];
}
$table = "glpi_plugin_fusioninventory_dblock".$type;
if ($DB->tableExists($table)) {
//Release the lock
$DB->delete(
$table,
$where
);
}
}
/**
* Clean all locks lasting more than 10 minutes
* @since 9.2+2.0
*
*/
function releaseAllLocks() {
$where = ['date' => ['<', new \QueryExpression("CURRENT_TIMESTAMP() - ".self::SECONDS_TO_RELEASE_LOCK)]];
$tables = [
'inventorynames',
'inventories',
'softwares',
'softwareversions'
];
foreach ($tables as $table) {
$this->releaseLock($table, $where);
}
}
}