mirror of
https://github.com/YunoHost-Apps/z-push_ynh.git
synced 2024-09-03 18:05:58 +02:00
299 lines
No EOL
9.6 KiB
PHP
299 lines
No EOL
9.6 KiB
PHP
<?php
|
|
/***********************************************
|
|
* File : topcollector.php
|
|
* Project : Z-Push
|
|
* Descr : available everywhere to collect
|
|
* data which could be displayed in z-push-top
|
|
* the 'persistent' flag should be used with care, so
|
|
* there is not too much information
|
|
*
|
|
* Created : 20.10.2011
|
|
*
|
|
* Copyright 2007 - 2013 Zarafa Deutschland GmbH
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License, version 3,
|
|
* as published by the Free Software Foundation with the following additional
|
|
* term according to sec. 7:
|
|
*
|
|
* According to sec. 7 of the GNU Affero General Public License, version 3,
|
|
* the terms of the AGPL are supplemented with the following terms:
|
|
*
|
|
* "Zarafa" is a registered trademark of Zarafa B.V.
|
|
* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
|
|
* The licensing of the Program under the AGPL does not imply a trademark license.
|
|
* Therefore any rights, title and interest in our trademarks remain entirely with us.
|
|
*
|
|
* However, if you propagate an unmodified version of the Program you are
|
|
* allowed to use the term "Z-Push" to indicate that you distribute the Program.
|
|
* Furthermore you may use our trademarks where it is necessary to indicate
|
|
* the intended purpose of a product or service provided you use it in accordance
|
|
* with honest practices in industrial or commercial matters.
|
|
* If you want to propagate modified versions of the Program under the name "Z-Push",
|
|
* you may only do so if you have a written permission by Zarafa Deutschland GmbH
|
|
* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
|
|
*
|
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Consult LICENSE file for details
|
|
************************************************/
|
|
|
|
class TopCollector extends InterProcessData {
|
|
const ENABLEDAT = 2;
|
|
const TOPDATA = 3;
|
|
|
|
protected $preserved;
|
|
protected $latest;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @access public
|
|
*/
|
|
public function TopCollector() {
|
|
// initialize super parameters
|
|
$this->allocate = 2097152; // 2 MB
|
|
$this->type = 20;
|
|
parent::__construct();
|
|
|
|
// initialize params
|
|
$this->InitializeParams();
|
|
|
|
$this->preserved = array();
|
|
// static vars come from the parent class
|
|
$this->latest = array( "pid" => self::$pid,
|
|
"ip" => Request::GetRemoteAddr(),
|
|
"user" => self::$user,
|
|
"start" => self::$start,
|
|
"devtype" => Request::GetDeviceType(),
|
|
"devid" => self::$devid,
|
|
"devagent" => Request::GetUserAgent(),
|
|
"command" => Request::GetCommandCode(),
|
|
"ended" => 0,
|
|
"push" => false,
|
|
);
|
|
|
|
$this->AnnounceInformation("initializing");
|
|
}
|
|
|
|
/**
|
|
* Destructor
|
|
* indicates that the process is shutting down
|
|
*
|
|
* @access public
|
|
*/
|
|
public function __destruct() {
|
|
$this->AnnounceInformation("OK", false, true);
|
|
}
|
|
|
|
/**
|
|
* Advices all other processes that they should start/stop
|
|
* collecting data. The data saved is a timestamp. It has to be
|
|
* reactivated every couple of seconds
|
|
*
|
|
* @param boolean $stop (opt) default false (do collect)
|
|
*
|
|
* @access public
|
|
* @return boolean indicating if it was set to collect before
|
|
*/
|
|
public function CollectData($stop = false) {
|
|
$wasEnabled = false;
|
|
|
|
// exclusive block
|
|
if ($this->blockMutex()) {
|
|
$wasEnabled = ($this->hasData(self::ENABLEDAT)) ? $this->getData(self::ENABLEDAT) : false;
|
|
|
|
$time = time();
|
|
if ($stop === true) $time = 0;
|
|
|
|
if (! $this->setData($time, self::ENABLEDAT))
|
|
return false;
|
|
$this->releaseMutex();
|
|
}
|
|
// end exclusive block
|
|
|
|
return $wasEnabled;
|
|
}
|
|
|
|
/**
|
|
* Announces a string to the TopCollector
|
|
*
|
|
* @param string $info
|
|
* @param boolean $preserve info should be displayed when process terminates
|
|
* @param boolean $terminating indicates if the process is terminating
|
|
*
|
|
* @access public
|
|
* @return boolean
|
|
*/
|
|
public function AnnounceInformation($addinfo, $preserve = false, $terminating = false) {
|
|
$this->latest["addinfo"] = $addinfo;
|
|
$this->latest["update"] = time();
|
|
|
|
if ($terminating) {
|
|
$this->latest["ended"] = time();
|
|
foreach ($this->preserved as $p)
|
|
$this->latest["addinfo"] .= " : ".$p;
|
|
}
|
|
|
|
if ($preserve)
|
|
$this->preserved[] = $addinfo;
|
|
|
|
// exclusive block
|
|
if ($this->blockMutex()) {
|
|
|
|
if ($this->isEnabled()) {
|
|
$topdata = ($this->hasData(self::TOPDATA)) ? $this->getData(self::TOPDATA): array();
|
|
|
|
$this->checkArrayStructure($topdata);
|
|
|
|
// update
|
|
$topdata[self::$devid][self::$user][self::$pid] = $this->latest;
|
|
$ok = $this->setData($topdata, self::TOPDATA);
|
|
}
|
|
$this->releaseMutex();
|
|
}
|
|
// end exclusive block
|
|
|
|
if ($this->isEnabled() === true && !$ok) {
|
|
ZLog::Write(LOGLEVEL_WARN, "TopCollector::AnnounceInformation(): could not write to shared memory. Z-Push top will not display this data.");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns all available top data
|
|
*
|
|
* @access public
|
|
* @return array
|
|
*/
|
|
public function ReadLatest() {
|
|
$topdata = array();
|
|
|
|
// exclusive block
|
|
if ($this->blockMutex()) {
|
|
$topdata = ($this->hasData(self::TOPDATA)) ? $this->getData(self::TOPDATA) : array();
|
|
$this->releaseMutex();
|
|
}
|
|
// end exclusive block
|
|
|
|
return $topdata;
|
|
}
|
|
|
|
/**
|
|
* Cleans up data collected so far
|
|
*
|
|
* @param boolean $all (optional) if set all data independently from the age is removed
|
|
*
|
|
* @access public
|
|
* @return boolean status
|
|
*/
|
|
public function ClearLatest($all = false) {
|
|
// it's ok when doing this every 10 sec
|
|
if ($all == false && time() % 10 != 0 )
|
|
return true;
|
|
|
|
$stat = false;
|
|
|
|
// exclusive block
|
|
if ($this->blockMutex()) {
|
|
if ($all == true) {
|
|
$topdata = array();
|
|
}
|
|
else {
|
|
$topdata = ($this->hasData(self::TOPDATA)) ? $this->getData(self::TOPDATA) : array();
|
|
|
|
$toClear = array();
|
|
foreach ($topdata as $devid=>$users) {
|
|
foreach ($users as $user=>$pids) {
|
|
foreach ($pids as $pid=>$line) {
|
|
// remove everything which terminated for 20 secs or is not updated for more than 120 secs
|
|
if (($line["ended"] != 0 && time() - $line["ended"] > 20) ||
|
|
time() - $line["update"] > 120) {
|
|
$toClear[] = array($devid, $user, $pid);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach ($toClear as $tc)
|
|
unset($topdata[$tc[0]][$tc[1]][$tc[2]]);
|
|
}
|
|
|
|
$stat = $this->setData($topdata, self::TOPDATA);
|
|
$this->releaseMutex();
|
|
}
|
|
// end exclusive block
|
|
|
|
return $stat;
|
|
}
|
|
|
|
/**
|
|
* Sets a different UserAgent for this connection
|
|
*
|
|
* @param string $agent
|
|
*
|
|
* @access public
|
|
* @return boolean
|
|
*/
|
|
public function SetUserAgent($agent) {
|
|
$this->latest["devagent"] = $agent;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Marks this process as push connection
|
|
*
|
|
* @param string $agent
|
|
*
|
|
* @access public
|
|
* @return boolean
|
|
*/
|
|
public function SetAsPushConnection() {
|
|
$this->latest["push"] = true;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Indicates if top data should be saved or not
|
|
* Returns true for 10 seconds after the latest CollectData()
|
|
* SHOULD only be called with locked mutex!
|
|
*
|
|
* @access private
|
|
* @return boolean
|
|
*/
|
|
private function isEnabled() {
|
|
$isEnabled = ($this->hasData(self::ENABLEDAT)) ? $this->getData(self::ENABLEDAT) : false;
|
|
return ($isEnabled !== false && ($isEnabled +300) > time());
|
|
}
|
|
|
|
/**
|
|
* Builds an array structure for the top data
|
|
*
|
|
* @param array $topdata reference to the topdata array
|
|
*
|
|
* @access private
|
|
* @return
|
|
*/
|
|
private function checkArrayStructure(&$topdata) {
|
|
if (!isset($topdata) || !is_array($topdata))
|
|
$topdata = array();
|
|
|
|
if (!isset($topdata[self::$devid]))
|
|
$topdata[self::$devid] = array();
|
|
|
|
if (!isset($topdata[self::$devid][self::$user]))
|
|
$topdata[self::$devid][self::$user] = array();
|
|
|
|
if (!isset($topdata[self::$devid][self::$user][self::$pid]))
|
|
$topdata[self::$devid][self::$user][self::$pid] = array();
|
|
}
|
|
}
|
|
|
|
?>
|