Source of file api.stardust.php
Size: 13,407 Bytes - Last Modified: 2024-04-27T15:26:05+03:00
/tmp/current_snapshot/api/libs/api.stardust.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 | <?php /** * Uncomplicated process manager */ class StarDust { /** * Contains current process name/identifier * * @var string */ protected $processName = ''; /** * System caching object placeholder * * @var object */ protected $cache = ''; /** * Contains current process states as processName=>processStats * * @var array */ protected $allProcessStates = array(); /** * Store each process state in separate STARDUST_PID cache keys * * @var bool */ protected $separateKeys = false; /** * Some predefined stuff */ const LOCK_NAME = 'stardustLockfree'; const LOCK_PREFIX = 'stardustPID_'; const CACHE_TIMEOUT = 2592000; const CACHE_KEY = 'STARDUST'; const REALTIME_PRECISSION = 5; public function __construct($processName = '', $separateKeys = false) { $this->setProcess($processName); $this->setZaWarudo($separateKeys); $this->initCache(); $this->loadCache(); } // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⢿⢻⣉⣳⣄⣀⣹⠾⠿⠶⠶⠶⠾⠿⣯⣿⣿⣿⣏⣿⣠⣿⣿⣿⣿⡿⠄⠀⠑⢒⡲⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⢾⠼⣿⣧⠦⠴⢒⣒⣒⣒⣒⣒⣒⣒⣒⣀⣤⠶⢶⣤⡏⣻⣿⣿⠿⢧⣤⠤⡤⢼⡯⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣴⣞⠿⠛⠉⠉⠉⠉⠉⡭⠭⣭⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⡿⣼⠃⠀⡨⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠴⠋⠁⠀⠀⠀⠀⠀⠐⠀⢉⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢿⣟⣫⣤⡴⢷⡟⣦⡞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⠋⠉⠁⠒⠒⠀⠀⠀⠠⠤⠤⠶⠾⠿⠿⢿⡿⡟⠛⠟⠏⢉⣁⣤⠬⠒⢛⣫⣿⣿⣾⣟⣿⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠙⢒⣶⢶⡖⣶⣶⡶⢦⣤⣴⢶⣶⣶⣾⣟⣿⣻⣇⢤⣴⣾⠿⣿⢿⢹⣿⡿⡿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⢴⣶⣒⡾⣿⣟⢧⠈⢿⡿⠺⠟⠓⣊⡴⢙⡏⠉⣏⢻⣉⠺⠿⣿⠾⠋⠘⡼⣿⡟⠁⠀⠀⠀⢀⡠⠤⠤⠤⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⢯⣿⣞⣷⣿⣿⢆⠁⢿⠡⠔⠚⢛⣿⣿⠟⡇⠀⡟⢿⣯⠿⠗⠂⢤⢀⢧⣿⣟⡁⠀⠀⡠⠚⢁⣤⢔⣒⣒⠒⠚⢦⠀⠀⠀⠀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢⣿⣿⣿⣿⣟⣿⡇⠘⡇⠀⠀⠩⠻⡁⠀⣇⠀⠃⠀⠀⠈⠀⠀⠈⡟⣸⣿⣿⣯⣿⡿⠁⣴⣿⠋⠁⠀⠀⠙⣦⢰⡇⠀⠀⠀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣤⣤⡈⢳⣿⣿⣿⣷⣧⠀⢃⠀⠀⠀⠀⢱⡀⡅⠀⡀⡄⠀⠀⠀⠀⣸⢡⣿⣿⣿⣿⣿⣇⣾⢻⣿⡻⣖⣦⣄⢠⣇⢀⡇⠀⠀⠀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡟⣎⢿⡌⢻⣿⣿⣿⣿⡆⠸⡄⠀⠀⠀⠀⠛⢿⣿⠛⠁⠀⠀⠀⢀⡇⣼⣿⣿⣿⣿⣿⣇⢸⣽⣿⣿⣷⣽⠺⣓⢾⣿⠁⣠⣄⡀⠀⠀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣇⠸⣮⢧⣏⡻⣿⣿⣿⣿⡷⢧⡀⠀⣀⣀⣤⣄⣠⣤⣀⡀⠀⢀⡜⡼⣿⢿⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⡮⣿⣮⠑⢌⠻⣋⣩⡙⢢⡀⠀⠀ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣋⣮⣆⡾⣸⡿⠹⡞⣿⣿⣿⣇⣸⣳⡀⠉⣅⣀⣉⣉⣀⣉⠉⢀⣮⣾⠇⡌⠓⢝⣿⣿⣿⣿⣿⣿⠁⣉⠁⠀⠈⡝⢦⡀⡷⠈⣯⡻⣦⡈⢆⠀ // ⠀⠀⠀⠀⠀⣀⢤⢚⣉⡓⠚⠉⠲⣿⣿⣿⣿⣯⣿⡄⣽⣿⣿⣿⣿⣿⣷⣵⡀⠈⢻⠉⠙⠛⠋⣠⣿⣿⠏⠀⠰⡄⠀⠙⠻⣿⣿⣿⣿⣾⡇⠀⠀⢀⠇⠦⣣⠃⣼⠻⢿⡎⣿⣄⠱ // ⡀⠀⠴⠒⠉⠀⢿⣾⣾⣿⣷⣄⠀⢾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢈⠻⣿⣄⡟⠀⠀⠀⣰⣿⣿⡟⣰⠸⣆⢹⡄⣄⡀⠈⠛⠉⣻⣿⡇⠀⠀⡼⠈⡦⣿⣶⣿⣿⣾⠵⣶⣛⢧ // ⠀⠀⠀⠀⠀⠀⠈⠹⠽⣿⣿⣻⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⢻⣎⠻⢿⣶⣶⣶⣿⣿⣿⠀⢹⣇⠈⠳⣿⣾⣟⣷⣾⣾⡿⢻⣿⣄⠀⢣⠶⣱⣿⣿⣾⣿⣧⡒⠻⣿⠸ // ⠀⠀⠀⠀⠀⠀⢀⣀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠻⡄⢈⣿⣟⢿⣿⡟⢸⡀⠈⣿⠀⠀⢈⣿⡿⠛⠋⠀⠈⠁⣿⣿⣶⠌⡧⣿⣿⣿⣿⣿⣿⣿⡄⠙⢣ // ⠀⠀⠀⢀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣤⣶⣿⣿⣿⣿⡀⢻⠀⠀⣷⣄⣷⣀⡴⠏⠁⠀⠀⠀⠀⠀⣰⢟⣿⣿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀ /** * Inits system caching instance for further usage * * @return void */ protected function initCache() { $this->cache = new UbillingCache(); } /** * Loads current processes data from cache * * @return void */ protected function loadCache() { $this->allProcessStates = $this->getCachedData(); } /** * Sets instance process name/identifier * * @param string $processName * * @return void */ public function setProcess($processName = '') { $this->processName = $processName; } /** * Sets instance process separate keys usage flag * * @param string $processName * * @return void */ public function setZaWarudo($state = false) { $this->separateKeys = $state; } /** * Returns process data from cache * * @return array */ protected function getCachedData() { $result = array(); if ($this->separateKeys) { $allCacheKeys = $this->cache->getAllcache(); if (!empty($allCacheKeys)) { $processKeyMask = UbillingCache::CACHE_PREFIX . self::CACHE_KEY . '_'; foreach ($allCacheKeys as $io => $eachKey) { if (strpos($eachKey, $processKeyMask) !== false) { $processNameClean = str_replace($processKeyMask, '', $eachKey); $processCacheKey = self::CACHE_KEY . '_' . $processNameClean; $result[$processNameClean] = $this->cache->get($processCacheKey, self::CACHE_TIMEOUT); } } } } else { $cachedData = $this->cache->get(self::CACHE_KEY, self::CACHE_TIMEOUT); if (!empty($cachedData)) { $result = $cachedData; } } return($result); } /** * Saves current process data into cache * * @return void */ protected function saveCache() { if ($this->separateKeys) { $this->cache->set(self::CACHE_KEY . '_' . $this->processName, $this->allProcessStates[$this->processName], self::CACHE_TIMEOUT); } else { $this->cache->set(self::CACHE_KEY, $this->allProcessStates, self::CACHE_TIMEOUT); } } /** * Checks is process name not empty and valid for setting/getting locks? * * @return bool * @throws Exception */ protected function pidIsOk() { $result = false; if (!empty($this->processName)) { $result = true; } else { throw new Exception('EX_EMPTY_PID'); } return($result); } /** * Starts some process * * @return void */ public function start() { if ($this->pidIsOk()) { $this->processStateUpdate(false); nr_query("SELECT GET_LOCK('" . self::LOCK_PREFIX . $this->processName . "',1)"); } } /** * Stops some process * * @return void */ public function stop() { if ($this->pidIsOk()) { $this->processStateUpdate(true); nr_query("SELECT RELEASE_LOCK('" . self::LOCK_PREFIX . $this->processName . "')"); } } /** * Performs check is database lock available or not? * * @return bool */ protected function isLocked() { $result = true; if ($this->pidIsOk()) { $query = "SELECT IS_FREE_LOCK('" . self::LOCK_PREFIX . $this->processName . "') AS " . self::LOCK_NAME; $rawReply = simple_query($query); $result = ($rawReply[self::LOCK_NAME]) ? false : true; } return($result); } /** * Performs check for current process is running * * @return bool */ public function isRunning() { $locked = $this->isLocked(); $result = ($locked) ? true : false; return($result); } /** * Performs check for current process is not running * * @return bool */ public function notRunning() { $locked = $this->isLocked(); $result = ($locked) ? false : true; return($result); } /** * Returns current process execution stats * * @return array */ public function getState() { $result = array(); if (!empty($this->processName)) { $processData = $this->getCachedData(); if (isset($processData[$this->processName])) { $result = $processData[$this->processName]; //process now running? if (!$result['finished']) { $result['realtime'] = round((microtime(true) - $result['ms']), self::REALTIME_PRECISSION); } } } return($result); } /** * Returns all process execution stats * * @return array */ public function getAllStates() { $result = array(); $processData = $this->getCachedData(); if (!empty($processData)) { $microTime = microtime(true); foreach ($processData as $processName => $eachProcessData) { //updating realtime if process is still running if (!$eachProcessData['finished']) { $eachProcessData['realtime'] = round($microTime - $eachProcessData['ms'], self::REALTIME_PRECISSION); } //append to results $result[$processName] = $eachProcessData; } } return($result); } /** * Updates some process execution stats * * @param bool $finished process finished or not flag * * @return void */ protected function processStateUpdate($finished = false) { $startTime = 0; $endTime = 0; $realTime = 0; $ms = 0; $me = 0; $nowTime = time(); $microTime = microtime(true); $finishedData = ($finished) ? 1 : 0; //process just started? if (!$finished) { $startTime = $nowTime; $ms = $microTime; } //process finished? if ($finished) { if (isset($this->allProcessStates[$this->processName])) { $startTime = $this->allProcessStates[$this->processName]['start']; $ms = $this->allProcessStates[$this->processName]['ms']; } else { $startTime = $nowTime; } $me = $microTime; $endTime = $nowTime; } //process duration counter if (isset($this->allProcessStates[$this->processName])) { if ($finished) { $realTime = $me - $ms; } else { $realTime = 0; } } //getting latest data from cache $this->loadCache(); //updating current process properties $this->allProcessStates[$this->processName]['start'] = $startTime; $this->allProcessStates[$this->processName]['end'] = $endTime; $this->allProcessStates[$this->processName]['realtime'] = round($realTime, self::REALTIME_PRECISSION); $this->allProcessStates[$this->processName]['ms'] = $ms; $this->allProcessStates[$this->processName]['me'] = $me; $this->allProcessStates[$this->processName]['finished'] = $finishedData; $this->allProcessStates[$this->processName]['pid'] = getmypid(); //save current process data into cache $this->saveCache(); } /** * Runs execution of some command as background process * * @param string $command full executable path to run * @param int $timeout optional timeout after executing command * * @return void */ public function runBackgroundProcess($command, $timeout = 0) { if (!empty($command)) { $pipes = array(); proc_close(proc_open($command . ' > /dev/null 2>/dev/null &', array(), $pipes)); if ($timeout) { sleep($timeout); } } } // // ⠀ (\__/) // (•ㅅ•) SONO CHI NO SADAME // _ノヽ ノ\_ // `/ `/ ⌒Y⌒ Y ヽ // ( (三ヽ人 / | // | ノ⌒\  ̄ ̄ヽ ノ // ヽ___>、__/ // |( 王 ノ〈 (\__/) // /ミ`ー―彡\ (•ㅅ•) // / ╰ ╯ \ / \> } |