Back to index

d-push  2.0
topcollector.php
Go to the documentation of this file.
00001 <?php
00002 /***********************************************
00003 * File      :   topcollector.php
00004 * Project   :   Z-Push
00005 * Descr     :   available everywhere to collect
00006 *               data which could be displayed in z-push-top
00007 *               the 'persistent' flag should be used with care, so
00008 *               there is not too much information
00009 *
00010 * Created   :   20.10.2011
00011 *
00012 * Copyright 2007 - 2011 Zarafa Deutschland GmbH
00013 *
00014 * This program is free software: you can redistribute it and/or modify
00015 * it under the terms of the GNU Affero General Public License, version 3,
00016 * as published by the Free Software Foundation with the following additional
00017 * term according to sec. 7:
00018 *
00019 * According to sec. 7 of the GNU Affero General Public License, version 3,
00020 * the terms of the AGPL are supplemented with the following terms:
00021 *
00022 * "Zarafa" is a registered trademark of Zarafa B.V.
00023 * "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
00024 * The licensing of the Program under the AGPL does not imply a trademark license.
00025 * Therefore any rights, title and interest in our trademarks remain entirely with us.
00026 *
00027 * However, if you propagate an unmodified version of the Program you are
00028 * allowed to use the term "Z-Push" to indicate that you distribute the Program.
00029 * Furthermore you may use our trademarks where it is necessary to indicate
00030 * the intended purpose of a product or service provided you use it in accordance
00031 * with honest practices in industrial or commercial matters.
00032 * If you want to propagate modified versions of the Program under the name "Z-Push",
00033 * you may only do so if you have a written permission by Zarafa Deutschland GmbH
00034 * (to acquire a permission please contact Zarafa at trademark@zarafa.com).
00035 *
00036 * This program is distributed in the hope that it will be useful,
00037 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00038 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00039 * GNU Affero General Public License for more details.
00040 *
00041 * You should have received a copy of the GNU Affero General Public License
00042 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00043 *
00044 * Consult LICENSE file for details
00045 ************************************************/
00046 
00047 class TopCollector extends InterProcessData {
00048     const ENABLEDAT = 2;
00049     const TOPDATA = 3;
00050 
00051     protected $preserved;
00052     protected $latest;
00053 
00059     public function TopCollector() {
00060         // initialize super parameters
00061         $this->allocate = 2097152; // 2 MB
00062         $this->type = 20;
00063         parent::__construct();
00064 
00065         // initialize params
00066         $this->InitializeParams();
00067 
00068         $this->preserved = array();
00069         // static vars come from the parent class
00070         $this->latest = array(  "pid"       => self::$pid,
00071                                 "ip"        => Request::GetRemoteAddr(),
00072                                 "user"      => self::$user,
00073                                 "start"     => self::$start,
00074                                 "devtype"   => Request::GetDeviceType(),
00075                                 "devid"     => self::$devid,
00076                                 "devagent"  => Request::GetUserAgent(),
00077                                 "command"   => Request::GetCommandCode(),
00078                                 "ended"     => 0,
00079                                 "push"      => false,
00080                         );
00081 
00082         $this->AnnounceInformation("initializing");
00083     }
00084 
00091     public function __destruct() {
00092         $this->AnnounceInformation("terminated", false, true);
00093     }
00094 
00105     public function CollectData($stop = false) {
00106         $wasEnabled = false;
00107 
00108         // exclusive block
00109         if ($this->blockMutex()) {
00110             $wasEnabled = ($this->hasData(self::ENABLEDAT)) ? $this->getData(self::ENABLEDAT) : false;
00111 
00112             $time = time();
00113             if ($stop === true) $time = 0;
00114 
00115             if (! $this->setData($time, self::ENABLEDAT))
00116                 return false;
00117             $this->releaseMutex();
00118         }
00119         // end exclusive block
00120 
00121         return $wasEnabled;
00122     }
00123 
00134     public function AnnounceInformation($addinfo, $preserve = false, $terminating = false) {
00135         $this->latest["addinfo"] = $addinfo;
00136         $this->latest["update"] = time();
00137 
00138         if ($terminating) {
00139             $this->latest["ended"] = time();
00140             foreach ($this->preserved as $p)
00141                 $this->latest["addinfo"] .= " : ".$p;
00142         }
00143 
00144         if ($preserve)
00145             $this->preserved[] = $addinfo;
00146 
00147         // exclusive block
00148         if ($this->blockMutex()) {
00149 
00150             if ($this->isEnabled()) {
00151                 $topdata = ($this->hasData(self::TOPDATA)) ? $this->getData(self::TOPDATA): array();
00152 
00153                 $this->checkArrayStructure($topdata);
00154 
00155                 // update
00156                 $topdata[self::$devid][self::$user][self::$pid] = $this->latest;
00157                 $ok = $this->setData($topdata, self::TOPDATA);
00158             }
00159             $this->releaseMutex();
00160         }
00161         // end exclusive block
00162 
00163         if ($this->isEnabled() === true && !$ok) {
00164             ZLog::Write(LOGLEVEL_WARN, "TopCollector::AnnounceInformation(): could not write to shared memory. Z-Push top will not display this data.");
00165             return false;
00166         }
00167 
00168         return true;
00169     }
00170 
00177     public function ReadLatest() {
00178         $topdata = array();
00179 
00180         // exclusive block
00181         if ($this->blockMutex()) {
00182             $topdata = ($this->hasData(self::TOPDATA)) ? $this->getData(self::TOPDATA) : array();
00183             $this->releaseMutex();
00184         }
00185         // end exclusive block
00186 
00187         return $topdata;
00188     }
00189 
00198     public function ClearLatest($all = false) {
00199         // it's ok when doing this every 10 sec
00200         if ($all == false && time() % 10 != 0 )
00201             return true;
00202 
00203         $stat = false;
00204 
00205         // exclusive block
00206         if ($this->blockMutex()) {
00207             if ($all == true) {
00208                 $topdata = array();
00209             }
00210             else {
00211                 $topdata = ($this->hasData(self::TOPDATA)) ? $this->getData(self::TOPDATA) : array();
00212 
00213                 $toClear = array();
00214                 foreach ($topdata as $devid=>$users) {
00215                     foreach ($users as $user=>$pids) {
00216                         foreach ($pids as $pid=>$line) {
00217                             // remove everything which terminated for 20 secs or is not updated for more than 120 secs
00218                             if (($line["ended"] != 0 && time() - $line["ended"] > 20) ||
00219                                 time() - $line["update"] > 120) {
00220                                 $toClear[] = array($devid, $user, $pid);
00221                             }
00222                         }
00223                     }
00224                 }
00225                 foreach ($toClear as $tc)
00226                     unset($topdata[$tc[0]][$tc[1]][$tc[2]]);
00227             }
00228 
00229             $stat = $this->setData($topdata, self::TOPDATA);
00230             $this->releaseMutex();
00231         }
00232         // end exclusive block
00233 
00234         return $stat;
00235     }
00236 
00245     public function SetUserAgent($agent) {
00246         $this->latest["devagent"] = $agent;
00247     }
00248 
00257     public function SetAsPushConnection() {
00258         $this->latest["push"] = true;
00259     }
00260 
00269     private function isEnabled() {
00270         $isEnabled = ($this->hasData(self::ENABLEDAT)) ? $this->getData(self::ENABLEDAT) : false;
00271         return ($isEnabled !== false && ($isEnabled +300) > time());
00272     }
00273 
00282     private function checkArrayStructure(&$topdata) {
00283         if (!isset($topdata) || !is_array($topdata))
00284             $topdata = array();
00285 
00286         if (!isset($topdata[self::$devid]))
00287             $topdata[self::$devid] = array();
00288 
00289         if (!isset($topdata[self::$devid][self::$user]))
00290             $topdata[self::$devid][self::$user] = array();
00291 
00292         if (!isset($topdata[self::$devid][self::$user][self::$pid]))
00293             $topdata[self::$devid][self::$user][self::$pid] = array();
00294     }
00295 }
00296 
00297 ?>