. * * ------------------------------------------------------------------------ * * 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(" ERROR: Timeout for DB lock based on name "); $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); } } }