update
This commit is contained in:
489
core/class/Daemon.class.php
Normal file
489
core/class/Daemon.class.php
Normal file
@@ -0,0 +1,489 @@
|
||||
<?php
|
||||
|
||||
// Logowanie
|
||||
define('DLOG_TO_CONSOLE', 1);
|
||||
define('DLOG_NOTICE', 2);
|
||||
define('DLOG_WARNING', 4);
|
||||
define('DLOG_ERROR', 8);
|
||||
define('DLOG_CRITICAL', 16);
|
||||
|
||||
/**
|
||||
* Daemon
|
||||
*
|
||||
* Wymagania:
|
||||
* Unix
|
||||
* PHP 4 >= 4.3.0 or PHP 5
|
||||
* PHP z:
|
||||
* --enable-sigchild
|
||||
* --enable-pcntl
|
||||
*/
|
||||
class Daemon
|
||||
{
|
||||
|
||||
private $userID = 99;
|
||||
|
||||
public $x=0;
|
||||
|
||||
private $groupID = 99;
|
||||
|
||||
/**
|
||||
* Zakonczyc prace gdy nie da sie ustawic tozsamosci demona ?
|
||||
*/
|
||||
private $requireSetIdentity = false;
|
||||
|
||||
/**
|
||||
* sciezka do pida
|
||||
*
|
||||
*/
|
||||
private $pidFileLocation = '/home/users/turystyka/public_html/test/daemon.pid';
|
||||
|
||||
/**
|
||||
* sciezka home'a.. tylko po co?
|
||||
*
|
||||
*/
|
||||
private $homePath = '/home/users/turystyka/public_html/Server/Daemon';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* id procesu
|
||||
*
|
||||
*/
|
||||
protected $pid = 0;
|
||||
|
||||
/**
|
||||
* czy proces jest dzieckiem
|
||||
*
|
||||
*/
|
||||
private $isChildren = false;
|
||||
|
||||
/**
|
||||
* czy dzialamy czy nie :)
|
||||
*
|
||||
*/
|
||||
private $isRunning = false;
|
||||
|
||||
private $children = array();
|
||||
|
||||
private $maxProcesses = 10;
|
||||
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
*/
|
||||
public function __construct($homePath, $pidFileLocation) {
|
||||
error_reporting(0);
|
||||
set_time_limit(0);
|
||||
ob_implicit_flush();
|
||||
|
||||
register_shutdown_function(array(&$this, 'releaseDaemon'));
|
||||
}
|
||||
|
||||
public function GetUserID() {
|
||||
return $this->userID;
|
||||
}
|
||||
|
||||
public function SetUserID($userID) {
|
||||
$this->userID = $userID;
|
||||
}
|
||||
|
||||
public function GetGroupID() {
|
||||
return $this->groupID;
|
||||
}
|
||||
|
||||
public function SetGroupID($groupID) {
|
||||
$this->groupID = $groupID;
|
||||
}
|
||||
|
||||
public function GetRequireSetIdentity() {
|
||||
return $this->requireSetIdentity;
|
||||
}
|
||||
|
||||
public function SetRequireSetIdentity($requireSetIdentity) {
|
||||
$this->requireSetIdentity = $requireSetIdentity;
|
||||
}
|
||||
|
||||
public function GetPidFileLocation() {
|
||||
return $this->pidFileLocation;
|
||||
}
|
||||
|
||||
public function SetPidFileLocation($pidFileLocation) {
|
||||
$this->pidFileLocation = $pidFileLocation;
|
||||
}
|
||||
|
||||
public function GetHomePath() {
|
||||
return $this->homePath;
|
||||
}
|
||||
|
||||
public function SetHomePath($homePath) {
|
||||
$this->homePath = $homePath;
|
||||
}
|
||||
|
||||
public function GetPid() {
|
||||
return $this->pid;
|
||||
}
|
||||
|
||||
public function SetPid($pid) {
|
||||
$this->pid = $pid;
|
||||
$fp = fopen($this->GetHomePath().'/'.$this->pid.'.pid', 'w');
|
||||
fwrite($fp, serialize($this));
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
public function GetIsChildren() {
|
||||
return $this->isChildren;
|
||||
}
|
||||
|
||||
public function SetIsChildren($isChildren) {
|
||||
$this->isChildren = $isChildren;
|
||||
}
|
||||
|
||||
public function GetIsRunning() {
|
||||
return $this->isRunning;
|
||||
}
|
||||
|
||||
public function SetIsRunning($isRunning) {
|
||||
$this->isRunning = $isRunning;
|
||||
}
|
||||
|
||||
public function GetChildren() {
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
public function AddChild($pid) {
|
||||
$this->children[$pid] = true;
|
||||
}
|
||||
|
||||
public function RemChild($pid) {
|
||||
if(isset($this->children[$pid])) {
|
||||
unset($this->childern[$pid]);
|
||||
}
|
||||
}
|
||||
|
||||
public function StartChild($child) {
|
||||
|
||||
$pid = Daemon::InitChild($chils, $this->GetPid());
|
||||
$this->AddChild($pid);
|
||||
MFLog::DbLog('Child process '.$pid.' started');
|
||||
if(!is_dir($filename)) {
|
||||
mkdir($this->GetHomePath().'/'.$this->GetPid(), 0777);
|
||||
}
|
||||
$fp = fopen($this->GetHomePath().'/'.$this->GetPid().'/'.$pid.'.pid', 'w');
|
||||
fwrite($fp, serialize($child));
|
||||
fclose($fp);
|
||||
$pidReturn = pcntl_waitpid($pid, $status);
|
||||
if(pcntl_wifexited($status)) {
|
||||
MFLog::DbLog('Child process '.$pid.' finished with status: '.$status);
|
||||
} else {
|
||||
MFLog::DbLog('child process '.$pid.' died');
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public static function InitChild($child, $masterPid) {
|
||||
$pid = pcntl_fork();
|
||||
if($pid == 0) {
|
||||
exit($child->Run($masterPid));
|
||||
} else {
|
||||
return $pid;
|
||||
}
|
||||
}
|
||||
|
||||
public function KillAll() {
|
||||
foreach($this->GetChildren() as $pid => $data) {
|
||||
MFLog::DbLog('Killing: '.$pid);
|
||||
posix_kill($pid, 0);
|
||||
if(is_file($this->GetHomePath().'/'.$this->GetPid().'/'.$pid.'.pid')) {
|
||||
unlink($this->GetHomePath().'/'.$this->GetPid().'/'.$pid.'.pid');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inicjowanie komponentow systemu
|
||||
*
|
||||
*/
|
||||
public function Init() {
|
||||
|
||||
//include('class/DB.class.php');
|
||||
//include('class/Registry.class.php');
|
||||
|
||||
|
||||
//include('ErrorHandler.php');
|
||||
$db = new DBProd();
|
||||
Registry::Remove('db');
|
||||
Registry::Set('db', $db);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Start daemona
|
||||
*
|
||||
*/
|
||||
public function Start() {
|
||||
$this->LogMessage('Starting daemon');
|
||||
|
||||
if (!$this->Daemonize())
|
||||
{
|
||||
$this->LogMessage('Could not start daemon', DLOG_ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$this->LogMessage('Running...');
|
||||
|
||||
$this->IsRunning = true;
|
||||
|
||||
|
||||
while ($this->IsRunning)
|
||||
{
|
||||
$this->DoTask();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop daemona
|
||||
*
|
||||
*/
|
||||
public function Stop()
|
||||
{
|
||||
$this->LogMessage('Stoping daemon');
|
||||
|
||||
$this->KillAll();
|
||||
|
||||
if(is_file($this->GetHomePath().'/'.$this->pid.'.pid')) {
|
||||
unlink($this->GetHomePath().'/'.$this->pid.'.pid');
|
||||
}
|
||||
|
||||
$this->IsRunning = false;
|
||||
//posix_kill($this->GetPid(), 0);
|
||||
//exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Podaj lape :)
|
||||
*
|
||||
*/
|
||||
function DoTask()
|
||||
{
|
||||
|
||||
while(1) {
|
||||
if(is_dir($this->GetHomePath().'/todo')) {
|
||||
if($handle = opendir($this->GetHomePath().'/todo')) {
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
if(count($this->GetChildren()) < $this->maxProcesses) {
|
||||
$taskFile = fopen($this->GetHomePath().'/todo/'.$file, 'r');
|
||||
$taskData = fread($taskFile, filesize($this->GetHomePath().'/todo/'.$file));
|
||||
fclose($taskFile);
|
||||
unlink($this->GetHomePath().'/todo/'.$file);
|
||||
$taskObj = unserialize($taskData);
|
||||
$this->InitChild($taskObj, $this->GetPid());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hau hau
|
||||
//mail('pawy@formix.pl', 'demonizer', 'im running');
|
||||
// $fp = fopen('/home/users/turystyka/public_html/test/data'.$this->x.'.txt', 'w');
|
||||
// fwrite($fp, '1');
|
||||
// fwrite($fp, '23');
|
||||
// fclose($fp);
|
||||
// sleep(10);
|
||||
// //$fp = fopen('/home/users/turystyka/public_html/test/data2.txt', 'w');
|
||||
// $this->x++;
|
||||
// if($this->x < 5){
|
||||
// $this->DoTask();
|
||||
// } else {
|
||||
// $this->Stop();
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Logujemy cos
|
||||
*
|
||||
*/
|
||||
public function LogMessage($msg, $level = DLOG_NOTICE)
|
||||
{
|
||||
// logowanie
|
||||
MFLog::DbLog($msg);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nie taki diabel straszny..
|
||||
*
|
||||
*/
|
||||
private function Daemonize()
|
||||
{
|
||||
// ob_end_flush();
|
||||
|
||||
if ($this->IsDaemonRunning())
|
||||
{
|
||||
// Deamon dziala. Exiting
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->Fork())
|
||||
{
|
||||
// niesforkowalo sie. Exiting.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->SetIdentity() && $this->requireSetIdentity)
|
||||
{
|
||||
// nie udalo sie ustawic tozsamosci. Exiting
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!posix_setsid())
|
||||
{
|
||||
$this->LogMessage('Could not make the current process a session leader', DLOG_ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$fp = @fopen($this->pidFileLocation, 'w'))
|
||||
{
|
||||
$this->LogMessage('Could not write to PID file', DLOG_ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs($fp, $this->pid);
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
@chdir($this->homePath);
|
||||
umask(0);
|
||||
|
||||
declare(ticks = 1);
|
||||
|
||||
pcntl_signal(SIGCHLD, array(&$this, 'sigHandler'));
|
||||
pcntl_signal(SIGTERM, array(&$this, 'sigHandler'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* sprawdzamy czy dzialamy juz
|
||||
*
|
||||
*/
|
||||
private function IsDaemonRunning()
|
||||
{
|
||||
$oldPid = false;
|
||||
if(is_file($this->pidFileLocation)) {
|
||||
$oldPid = @file_get_contents($this->pidFileLocation);
|
||||
|
||||
}
|
||||
if ($oldPid !== false && posix_kill(trim($oldPid),0))
|
||||
{
|
||||
$this->LogMessage('Daemon already running with PID: '.$oldPid, (DLOG_TO_CONSOLE | DLOG_ERROR));
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forkujemy proces
|
||||
*/
|
||||
private function Fork()
|
||||
{
|
||||
$this->LogMessage('Forking...');
|
||||
|
||||
$pid = pcntl_fork();
|
||||
|
||||
if ($pid == -1) // error
|
||||
{
|
||||
$this->LogMessage('Could not fork', DLOG_ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
else if ($pid) // parent
|
||||
{
|
||||
$this->LogMessage('Killing parent');
|
||||
|
||||
exit();
|
||||
}
|
||||
else // children
|
||||
{
|
||||
|
||||
$this->IsChildren = true;
|
||||
$this->SetPid(posix_getpid());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ustawiamy tozsamosc diob³a i zwracamy wynik
|
||||
*
|
||||
*/
|
||||
private function SetIdentity()
|
||||
{
|
||||
if (!posix_setgid($this->groupID) || !posix_setuid($this->userID))
|
||||
{
|
||||
$this->LogMessage('Could not set identity', DLOG_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obsluga sig'ow
|
||||
*
|
||||
*/
|
||||
public function SigHandler($sigNo)
|
||||
{
|
||||
switch ($sigNo)
|
||||
{
|
||||
case SIGTERM: // Shutdown
|
||||
$this->LogMessage('Shutdown signal');
|
||||
$this->Stop();
|
||||
exit();
|
||||
break;
|
||||
|
||||
case SIGCHLD: // Halt
|
||||
$this->LogMessage('Halt signal');
|
||||
while (pcntl_waitpid(-1, $status, WNOHANG) > 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zwalnia plik z pidem
|
||||
* Cos ala desktruktor
|
||||
*
|
||||
*/
|
||||
public function ReleaseDaemon()
|
||||
{
|
||||
if (file_exists($this->pidFileLocation))
|
||||
// if ($this->isChildren && file_exists($this->pidFileLocation))
|
||||
{
|
||||
$this->LogMessage('Releasing daemon');
|
||||
|
||||
unlink($this->pidFileLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user